С#:Хорошая и эффективная реализация IEnumerable<T>.HasDuplications.
-
16-09-2019 - |
Вопрос
Есть ли у кого-нибудь хороший и эффективный метод расширения для поиска дубликатов в последовательности элементов?
Думаю, я мог бы поставить 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;
}
}
}
Не связан с StackOverflow