С#:Хорошая и эффективная реализация IEnumerable<T>.HasDuplications.

StackOverflow https://stackoverflow.com/questions/1134180

Вопрос

Есть ли у кого-нибудь хороший и эффективный метод расширения для поиска дубликатов в последовательности элементов?

Думаю, я мог бы поставить return subjects.Distinct().Count() == subjects.Count() в метод расширения, но кажется, что должен быть лучший способ.Этот метод должен был бы дважды пересчитывать элементы и сортировать все отдельные элементы.Лучшая реализация должна возвращать true при первом найденном дубликате.Есть хорошие предложения?

Я предполагаю, что схема может быть примерно такой:

public static bool HasDuplicates<T>(this IEnumerable<T> subjects)
{
    return subjects.HasDuplicates(EqualityComparer<T>.Default);
}

public static bool HasDuplicates<T>(this IEnumerable<T> subjects, IEqualityComparer<T> comparer)
{
    ...
}

Но не совсем уверен, насколько разумной будет его реализация...

Это было полезно?

Решение

public static bool HasDuplicates<T>(this IEnumerable<T> subjects)
{
    return HasDuplicates(subjects, EqualityComparer<T>.Default);
}

public static bool HasDuplicates<T>(this IEnumerable<T> subjects, IEqualityComparer<T> comparer)
{
    HashSet<T> set = new HashSet<T>(comparer);
    foreach (T item in subjects)
    {
        if (!set.Add(item))
            return true;
    }

    return false;
}

Другие советы

Это в производственном коде.Прекрасно работает:

public static bool HasDuplicates<T>(this IEnumerable<T> sequence) {
    var set = new HashSet<T>();
    return !sequence.All(item => set.Add(item));
}

Я думаю, что самый простой метод расширения следующий.

public static bool HasDuplicates<T>(this IEnumerable<T> enumerable) {
  var hs = new HashSet<T>();
  foreach ( var cur in enumerable ) {
    if ( !hs.Add(cur) ) {
      return false;
    }
  }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top