C# 我是否可以使用LINQ来确定列表中的给定属性是否重复自身?

C# 我是否可以使用LINQ来确定列表中的给定属性是否重复自身?,c#,linq,C#,Linq,我有一个对象列表,上面有一个名称字段 我想知道是否有办法判断列表中的所有名称字段是否唯一 我可以只做两个循环并对每个值遍历列表,但我想知道是否有更干净的方法使用LINQ来实现这一点 我发现了一些示例,其中他们将列表中的每个项目与硬编码的值进行比较,但在我的示例中,我希望比较每个对象上的名称字段,并获得一个布尔值。检查唯一性的常见技巧是将删除重复项的列表的长度与原始列表的长度进行比较: bool allNamesAreUnique = myList.Select(x => x.Name).D

我有一个对象列表,上面有一个名称字段

我想知道是否有办法判断列表中的所有名称字段是否唯一

我可以只做两个循环并对每个值遍历列表,但我想知道是否有更干净的方法使用LINQ来实现这一点


我发现了一些示例,其中他们将列表中的每个项目与硬编码的值进行比较,但在我的示例中,我希望比较每个对象上的名称字段,并获得一个布尔值。

检查唯一性的常见技巧是将删除重复项的列表的长度与原始列表的长度进行比较:

bool allNamesAreUnique = myList.Select(x => x.Name).Distinct().Count() == myList.Count();
选择x=>x。Name将您的列表转换为仅包含姓名的列表,然后 Distict删除重复项。 性能应该是,这比On²嵌套循环解决方案要好

另一个选项是按名称对列表进行分组,并检查这些组的大小。这样做的另一个好处是告诉您哪些值不是唯一的:

var duplicates = myList.GroupBy(x => x.Name).Where(g => g.Count() > 1);

bool hasDuplicates = duplicates.Any();  // or
List<string> duplicateNames = duplicates.Select(g => g.Key).ToList();

虽然您可以使用LINQ来分组或创建一个不同的列表,然后将逐项与原始列表进行比较,但这会带来一些您可能不想要的开销,特别是对于非常大的列表。更有效的解决方案是将密钥存储在HashSet中,HashSet具有更好的查找功能,并在单个循环中检查重复项。此解决方案仍然使用一点LINQ,因此它满足您的需求

static public class ExtensionMethods
{
    static public bool HasDuplicates<TItem,TKey>(this IEnumerable<TItem> source, Func<TItem,TKey> func)
    {
        var found = new HashSet<TKey>();
        foreach (var key in source.Select(func))
        {
            if (found.Contains(key)) return true;
            found.Add(key);
        }
        return false;
    }
}
如果您希望不区分大小写:

var hasDuplicates = list.HasDuplicates( item => item.Name.ToUpper() );

发布您当前拥有的代码,我们无法为您提供其他帮助欢迎访问stackoverflow.com请向我们展示您的代码您可以使用LINQ GroupBy name,就像代码一样,只有答案不是很好helpful@maccettura:我完全同意。我通常会用一个只有代码的答案快速回答,以防止其他人浪费时间和精力来写相同的答案,然后用解释来扩展它。你发现我的答案太快了-一个很好的策略-当你发布时,我刚开始写同样的答案。@J.L有一个类似的解决方案,使用GroupBy并检查任何大于1的组。这还有一个额外的好处,那就是知道复制的是什么is@BradleyDotNET:说得好,我已将此选项添加到我的答案中。我喜欢您的解决方案,因为它会在找到第一个副本后立即停止遍历列表。我不喜欢以大写字母开头,但那可能就是我。作为此参数的名称。
var hasDuplicates = list.HasDuplicates( item => item.Name.ToUpper() );