Подтвердить что ты не робот

Проверка списка с нулевыми значениями для дубликатов в С#

В С# я могу использовать что-то вроде:

List<string> myList = new List<string>();

if (myList.Count != myList.Distinct().Count())
{
    // there are duplicates
}

проверить наличие дубликатов в списке. Однако, если в списке есть null элементы, это создает ложное срабатывание. Я могу сделать это, используя какой-то неаккуратный код, но есть ли способ проверить дубликаты в списке, не считая нулевые значения кратким способом?

4b9b3361

Ответ 1

Я бы сделал это по-другому:

Операторы Linq будут оцениваться лениво, .Any будет короткозамкнутым - это означает, что вам не нужно повторять и подсчитывать весь список, если есть дубликаты, и как таковые должны быть более эффективными.

var dupes = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Count() > 1);

if(dupes)
{
    //there are duplicates
}

EDIT: http://pastebin.com/b9reVaJu Некоторые тесты Linqpad, которые, как представляется, заключают GroupBy с Count() быстрее

РЕДАКТИРОВАТЬ 2: Нижеприведенный ответ Rawling выглядит как минимум в 5 раз быстрее, чем этот подход!

Ответ 2

Если вас беспокоит производительность, следующий код будет остановлен, как только он найдет первый дублирующий элемент - все остальные решения до сих пор требуют, чтобы весь ввод повторялся хотя бы один раз.

var hashset = new HashSet<string>();
if (myList.Where(s => s != null).Any(s => !hashset.Add(s)))
{
    // there are duplicates
}

hashset.Add возвращает false, если элемент уже существует в наборе, а Any возвращает true сразу после первого значения true, поэтому он будет искать только входные данные до первого дублировать.

Ответ 3

var nonNulls = myList.Where(x => x != null)
if (nonNulls.Count() != nonNulls.Distinct().Count())
{
    // there are duplicates
}

Ответ 4

Ну, два нуля - это дубликаты, не так ли?

В любом случае сравните список без нулей:

var denullified = myList.Where(l => l != null);
if(denullified.Count() != denullified.Distinct().Count()) ...

Ответ 5

ИЗМЕНИТЬ моя первая попытка сосет, потому что она не отложена.

вместо

var duplicates = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Skip(1).Any());

удалена бедная реализация.