Устранение повторов последующих элементов в списке

Я хочу преобразовать список A

A = {1, 12, 3, 3, 3, 8, 5, 5 }

в список B

B = {1, 12, 3, 8, 5 }

Как видите, пункты 3 и 5 повторяются в A, и эти повторы исключаются в B.

Код, который я создал для этого, следующий:

public IEnumerable<int> FilterRepeatingElements(IEnumerable<int> source) 
{
    return source
        .Select(x => (IEnumerable<int>)new[] { x })
        .Aggregate((a, b) => a.Last() != b.First() ? a.Concat(b) : a);
}

Это работает, но мне интересно, есть ли более выразительный способ сделать это с помощью «LINQ», с помощью классических методов .NET или методов из библиотеки, например Morelinq.

Спасибо!

РЕДАКТИРОВАТЬ

Я обнаружил, что у моего решения проблемы с таким вариантом использования:

FilterRepeatingElements(MoreEnumerable.Random()).Take(10)
  • MoreEnumerable.Random() генерирует бесконечную последовательность. Выполнение такого кода приводит к зависанию выполнения.

1 ответ
1

Хотя ответ aepot является хорошим ответом и получил мое одобрение, он работает только для типа int. Я знаю, что вопрос для примера использует int в своем коде, но если вы хотите, чтобы он работал для всех типов данных, необходимо немного изменить код.

public static class EnumerableExtensions
{
    public static IEnumerable<TSource> FilterRepeatingElements<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                var item = enumerator.Current;
                yield return item;

                while (enumerator.MoveNext())
                {
                    if (!comparer.Equals(item, enumerator.Current))
                    {
                        item = enumerator.Current;
                        yield return item;
                    }
                }
            }
        }
    }

    public static IEnumerable<TSource> FilterRepeatingElements<TSource>(this IEnumerable<TSource> source)
    {
        return FilterRepeatingElements(source, EqualityComparer<TSource>.Default);
    }
}

Это будет работать для любого типа и принимает те же параметры, что и linq Distinct, поскольку мы делаем «своего рода» отличное.

var data = new int[] { 1, 12, 3, 3, 3, 8, 5, 5 };
var postData = data.FilterRepeatingElements().ToArray();

var items = new string[] { "A", "A", "B", "C", "C", "D", "D" };
var postItems = items.FilterRepeatingElements().ToArray();

    Добавить комментарий

    Ваш адрес email не будет опубликован.