【问题标题】:C# Check Object Array For DuplicatesC# 检查对象数组是否重复
【发布时间】:2009-10-26 20:43:22
【问题描述】:

我有一个 Customer[] 对象数组,我想用它来创建 Dictionary。在加载字典之前检查数组是否重复的最简单方法是什么?我想避免“ArgumentException:已添加具有相同键的项目”。谢谢。

【问题讨论】:

  • 我想预先知道是否通过了重复项,还是在添加项目时即时检查。我可以使用 Dictionary.ContainsKey 但是我必须在数组中旋转两次,我想这并不可怕,我只是想知道是否有更简单的方法我不知道。谢谢。

标签: c# arrays dictionary no-duplicates


【解决方案1】:

只需在添加客户之前调用 Dictionary.ContainsKey(key)。

【讨论】:

    【解决方案2】:

    您可以同时使用 LINQ:

    Customer[] customers; // initialized somehow...
    var customerDictionary = customers.Distinct().ToDictionary( cust => cust.SomeKey );
    

    如果您要以不那么直接的方式构建字典,则可以使用 Distinct() 扩展方法来获得一个唯一的数组,如下所示:

    Customer[] uniqueCustomers = customers.Distinct().ToArray();
    

    如果您需要注意潜在的重复项,可以先使用GroupBy( c => c ) 来识别哪些项目有重复项。

    最后,如果您不想使用 LINQ,您可以动态构建字典并在添加每个项目时使用前置条件检查:

    var customerDictionary = new Dictionary<Customer,string>();
    foreach( var cust in customers )
    {
        if( !customerDictionary.ContainsKey(cust) )
            customerDictionary.Add( cust, cust.SomeKey ); 
    }
    

    【讨论】:

    • 我喜欢这种方法的外观,在这种情况下我不愿谈论性能,但在数组上调用 distinct 不会涉及进行大量比较吗? Dictionary.ContainsKey 相对 O(1)。
    • @Josh:我的理解是LINQ的Distinct()操作符在内部构建了一个hashset结构来优化它的性能。因此,它的性能应该比迭代地在列表中搜索重复项要好。阅读这个 SO 问题了解更多信息:stackoverflow.com/questions/146358/…
    【解决方案3】:

    从性能和代码的角度来看,最有效的方法是:

    dict[key] = value
    

    这样你提到的异常永远不会被抛出,并且key查找不会发生两次

    【讨论】:

    • +1 因为他没有说每个对象的值都是唯一的。
    【解决方案4】:

    数组有多大?重复的可能性有多大?

    将数组中的每个元素与其他元素进行比较是一项相当昂贵的操作。

    在添加每个项目之前调用Dictionary.ContainsKey(key) 会更快。

    注意:如果重复很少见,那么您可以使用异常处理,但这是不好的编程习惯。

    【讨论】:

    • 小阵列。这是我前进的方向,但我想在开始处理之前预先知道是否有骗子被传入。 Dictionary 中的字符串是来自与 Customer 对象关联的 Web 服务的一些响应 XML。
    • 对流控制使用异常处理并不是一种理想的做法。
    • 在流程流中使用异常的错误做法!
    【解决方案5】:

    在这种情况下,您对重复的定义是什么?

    如果它只是相同的对象实例(相同的指针),那么这很简单,您可以使用此处给出的其他答案中的任何方法。

    有时虽然相等的概念并不那么简单,但具有相同数据的不同对象实例是否相等?在这种情况下,您可能需要一个 IEqualityComparer 的实现来帮助您。

    【讨论】:

    • 假设两个具有相同 SSN 的 Customer 对象是骗子。
    • 啊,在这种情况下,您需要指定 Equality,因为指针的简单比较不会告诉您。
    • 因此,您可以将 SSD 用作字典中的键,或者对于更完整的解决方案,您可以实现一个 IEqualityComparer,您可以在一堆 linq 扩展方法中使用它。跨度>
    【解决方案6】:

    为什么不是这个??

    Customers.Distinct.ToDictionary(o=>o, GenerateString(o));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      • 2020-11-29
      • 2021-04-22
      • 2021-07-22
      • 1970-01-01
      相关资源
      最近更新 更多