Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing sequential repeating items from List<T> using linq

Tags:

c#

linq

I'm looking for a way to prevent repeating items in a list but still preserve the order. For example

1, 2, 3, 4, 4, 4, 1, 1, 2, 3, 4, 4 

should become

1, 2, 3, 4, 1, 2, 3, 4

I've done it quite inelegantly using a for loop, checking the next item as follows

    public static List<T> RemoveSequencialRepeats<T>(List<T> input) 
    {
        var result = new List<T>();

        for (int index = 0; index < input.Count; index++)
        {
            if (index == input.Count - 1)
            {
                result.Add(input[index]);
            }
            else if (!input[index].Equals(input[index + 1]))
            {
                result.Add(input[index]);
            }
        }

        return result;
    }

Is there a more elegant way to do this, preferably with LINQ?

like image 394
Ed W Avatar asked Aug 01 '13 07:08

Ed W


2 Answers

You can create extension method:

public static IEnumerable<T> RemoveSequentialRepeats<T>(
      this IEnumerable<T> source)
{
    using (var iterator = source.GetEnumerator())
    {
        var comparer = EqualityComparer<T>.Default;

        if (!iterator.MoveNext())
            yield break;

        var current = iterator.Current;
        yield return current;

        while (iterator.MoveNext())
        {
            if (comparer.Equals(iterator.Current, current))
                continue;

            current = iterator.Current;
            yield return current;
        }
    }        
}

Usage:

var result = items.RemoveSequentialRepeats().ToList();
like image 160
Sergey Berezovskiy Avatar answered Oct 06 '22 01:10

Sergey Berezovskiy


You can also use pure LINQ:

List<int> list = new List<int>{1, 2, 3, 4, 4, 4, 1, 1, 2, 3, 4, 4};
var result = list.Where((x, i) => i == 0 || x != list[i - 1]);
like image 28
King King Avatar answered Oct 06 '22 00:10

King King