The advantage of this solution compared to the accepted answer (by Simon Bartlett) is that it doesn't require a source of type IList<T>
to be efficient.
public static IEnumerable<TSource> ExcludeConsecutiveDuplicates<TSource>(
this IEnumerable<TSource> source,
IEqualityComparer<TSource> comparer = null)
{
ArgumentNullException.ThrowIfNull(source);
comparer ??= EqualityComparer<TSource>.Default;
(TSource Value, bool HasValue) previous = default;
foreach (var item in source)
{
bool isDuplicate = previous.HasValue && comparer.Equals(previous.Value, item);
if (!isDuplicate) yield return item;
previous = (item, true);
}
}
This approach is similar to AlexJ's answer, with the addition of an IEqualityComparer
parameter that allows to customize the equality check. I also removed the otherwise correct separation of argument-check and implementation, because this solution is not intended to be of library-grade quality. As for the name I adopted the ExcludeConsecutiveDuplicates
from AntonSemenov's answer.
Usage example:
var source = new string[]
{
"Red", "red", "blue", "green", "green", "red", "red", "yellow",
"WHITE", "white", "red", "white", "white"
};
var result = source.ExcludeConsecutiveDuplicates(StringComparer.OrdinalIgnoreCase);
Console.WriteLine($"Result: {String.Join(", ", result)}");
Output:
Result: Red, blue, green, red, yellow, WHITE, red, white
Online demo.