在 C# 中查找两个集合的补集的最快方法
Posted
技术标签:
【中文标题】在 C# 中查找两个集合的补集的最快方法【英文标题】:Quickest way to find the complement of two collections in C# 【发布时间】:2011-01-12 17:17:56 【问题描述】:我有两个ICollection<MyType>
类型的集合,分别称为c1
和c2
。我想找到在c2
中但不在c1
中的一组项目,其中相等的启发式是MyType
上的Id
属性。
在 C# (3.0) 中执行此操作的最快方法是什么?
【问题讨论】:
【参考方案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 => 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?以上是关于在 C# 中查找两个集合的补集的最快方法的主要内容,如果未能解决你的问题,请参考以下文章