Проверка списка с нулевыми значениями для дубликатов в С#
В С# я могу использовать что-то вроде:
List<string> myList = new List<string>();
if (myList.Count != myList.Distinct().Count())
{
// there are duplicates
}
проверить наличие дубликатов в списке. Однако, если в списке есть null
элементы, это создает ложное срабатывание. Я могу сделать это, используя какой-то неаккуратный код, но есть ли способ проверить дубликаты в списке, не считая нулевые значения кратким способом?
Ответы
Ответ 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());
удалена бедная реализация.