在c#中检查具有空值的列表是否重复

本文关键字:列表 是否 空值 检查 | 更新日期: 2023-09-27 18:17:07

在c#中,我可以使用:

List<string> myList = new List<string>();
if (myList.Count != myList.Distinct().Count())
{
    // there are duplicates
}

检查列表中的重复元素。然而,当列表中有null项时,会产生假阳性。我可以使用一些缓慢的代码来做到这一点,但是有没有一种方法可以检查列表中的重复项,同时用一种简洁的方式忽略空值?

在c#中检查具有空值的列表是否重复

如果您担心性能问题,下面的代码将在找到第一个重复项后立即停止—到目前为止,所有其他解决方案都要求至少迭代一次整个输入。

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,因此这将只搜索输入到第一个重复项。

我的做法不同:

给定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基准测试显示似乎GroupByCount()结合起来更快

编辑2:下面罗林的答案似乎比这个方法快至少5倍!

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

好吧,两个空是重复的,不是吗?

无论如何,比较没有空的列表:

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

EDIT我的第一次尝试很糟糕,因为它没有延迟。

相反,

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

较差的实现被删除。