【问题标题】:Quickest way to find the complement of two collections in C#在 C# 中查找两个集合的补集的最快方法
【发布时间】:2011-01-12 17:17:56
【问题描述】:

我有两个ICollection<MyType> 类型的集合,分别称为c1c2。我想找到在c2 中但不在c1 中的一组项目,其中相等的启发式是MyType 上的Id 属性。

在 C# (3.0) 中执行此操作的最快方法是什么?

【问题讨论】:

    标签: c# .net linq complement set-operations


    【解决方案1】:

    使用Enumerable.Except,特别是接受IEqualityComparer<MyType>overload

    var complement = c2.Except(c1, new MyTypeEqualityComparer());
    

    请注意,这会产生集合差异,因此c2 中的重复项只会在结果IEnumerable<MyType> 中出现一次。在这里你需要像这样实现IEqualityComparer<MyType>

    class MyTypeEqualityComparer : IEqualityComparer<MyType> {
        public bool Equals(MyType x, MyType y) {
            return x.Id.Equals(y.Id);
        }
    
        public int GetHashCode(MyType obj) {
            return obj.Id.GetHashCode();
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果使用 C# 3.0 + Linq:

      var complement = from i2 in c2
                       where c1.FirstOrDefault(i1 => i2.Id == i1.Id) == null
                       select i2;
      

      循环补码以获取项目。

      【讨论】:

      • 这样会使用嵌套循环,效率很低。
      • 也许使用where !c1.Any(i1 =&gt; i2.Id == i1.Id) 更有效?在这种情况下,您不会在 where 条件中检索任何值,您只需检查项目是否存在。见DotNetFiddle
      【解决方案3】:
      public class MyTypeComparer : IEqualityComparer<MyType>
      {
          public MyTypeComparer()
          {    
          }
      
          #region IComparer<MyType> Members
      
          public bool Equals(MyType x, MyType y)
          {
              return string.Equals(x.Id, y.Id);
          }
      
          public int GetHashCode(MyType obj)
          {
              return base.GetHashCode();
          }
      
          #endregion     
      }
      

      然后,使用 Linq:

      c3 collection = new collection().add(c1);
      c3.add(c2);
      var items = c3.Distinct(new MyTypeComparer());
      

      您也可以使用泛型和谓词来做到这一点。如果您需要样品,请告诉我。

      【讨论】:

      • 不会区分只是过滤掉重复项,让您使用 c1 union c2,而不是 c1- c2?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      相关资源
      最近更新 更多