在linq中设置相等

我有两个列表A和B(列表)。 如何以最便宜的方式确定它们是否相等? 我可以写一些类似’(A减B)联合(B减A)=空集’或将它们连接在一起并计算元素数量,但它相当昂贵。 有解决方法吗?

那么,这取决于你如何解释你的名单。

如果您将它们视为元组(因此列表中元素的顺序很重要),那么您可以使用以下代码:

public bool AreEqual(IList A, IList B) { if (A.Count != B.Count) return false; for (int i = 0; i < A.Count; i++) if (!A[i].Equals(B[i])) return false; } 

如果您将列表视为集合(因此元素的顺序无关紧要),那么......您使用的是错误的数据结构:

  public bool AreEqual(IList A, IList B) { HashSet setA = new HashSet(A); return setA.SetEquals(B); } 

如果列表项的顺序是相关的:

 bool areEqual = a.SequenceEqual(b); 

如果要将列表视为无序集:

 // assumes that the list items are ints bool areEqual = new HashSet(a).SetEquals(b); 

(如果需要该function, SequenceEqual方法和HashSet构造函数都具有带有IEqualityComparer参数的重载。)

这取决于你的意思“列表是平等的”。 如果你的意思是它们包含相同的对象,那么Daniel建议的解决方案很好,只需要Union()两个列表并计算项目。

如果通过“相等”表示它们具有相同顺序的相同项目,则最好比较两个列表的Count,然后如果它们具有相同的计数,则只需使用plain for loop进行迭代以比较每个元素来自同一索引的两个列表。 不太漂亮,但你很难快。

除非对列表进行排序,否则这里没有快捷方式,在这种情况下,您可以逐个比较元素。 显然我认为顺序无关紧要,否则显然你可以逐个比较它们。

否则,我建议您为大型项目列表获得的最有效算法可能是这样的,使用哈希表来跟踪您所看到的内容(警告:尚未测试,但它应该要清楚我得到了什么。)

 public static bool IsEqual(this List x1, List x2) { if(x1.Count != x2.Count) return false; var x1Elements = new Dictionary(); foreach(var item in x1) { int n; x1Elements.TryGetValue(item, out n); x1Elements[item] = n+1; } foreach(var item in x2) { int n; x1Elements.TryGetValue(item, out n); if(n <= 0) return false; // this element was in x2 but not x1 else x1Elements[item] = n-1; } // make sure x1 didn't have any elements // that weren't in x2 return x1Elements.Values.All(x => x == 0); } 

第一个镜头 – 如果它们包含相同的项目,则两个列表的并集应该具有与两个列表中的任何一个相同的项目数。

 listA.Union(listB).Count() == listA.Count() 

注意:如果一个列表为空,则失败。

但它可能仍然是O(n²)操作。

另一个解决方案 – 列表必须具有相同的长度和列表A减去列表B不得包含任何元素。

 (listA.Count() == listB.Count()) && !listA.Except(listB).Any()