4

Is it possible to replace every sequential duplicate using linq? I tried using groups with no success. Basically, I need to get the following results:

string[] arr = new [] { "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "a", "a" }; // input
string[] res = new [] { "a", "R", "R", "b", "R", "R", "R", "c", "R", "R", "a", "R" }; // output
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
Hirasawa Yui
  • 1,138
  • 11
  • 29

3 Answers3

7

Select method has an overload that takes the index, you can make use of it to check previous item:

res = arr.Select((x, idx) => idx != 0 && arr[idx - 1] == x ? "R" : x).ToArray();
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
-1

You could use John Skeets Extension which he stated here.

  public static IEnumerable<TResult> SelectWithPrevious<TSource, TResult>
    (this IEnumerable<TSource> source,
     Func<TSource, TSource, TResult> projection)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
             yield break;
        }
        TSource previous = iterator.Current;
        while (iterator.MoveNext())
        {
            yield return projection(previous, iterator.Current);
            previous = iterator.Current;
        }
    }
}

And then use it like this:

var out  = arr.SelectWithPrevious((prev, curr) => prev==curr? R:curr));
lorenzw
  • 366
  • 1
  • 10
-2

This works fine:

string[] arr = new [] { "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "a", "a" }; // input

string [] res = arr.StartWith("_").Zip(arr, (a0, a1) => a0 == a1 ? "R" : a1).ToArray();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172