LINQ:确定两个序列是否包含完全相同的元素

我需要确定两组是否包含完全相同的元素。 sorting并不重要。

例如,这两个数组应该被认为是相等的:

IEnumerable<int> data = new []{ 3,5,6,9 }; IEnumerable<int> otherData = new []{ 6,5,9,3} 

一组不能包含任何元素,不在其他。

这可以使用内置的查询操作符来完成吗? 考虑到元素的数量可以从几个到几百个,那么实现它的最有效的方法是什么呢?

如果您想将数组视为“集合”并忽略顺序和重复项目,则可以使用HashSet<T>.SetEquals方法 :

 var isEqual = new HashSet<int>(first).SetEquals(second); 

否则,你最好的办法是用相同的方法对两个序列进行SequenceEqual ,并使用SequenceEqual来比较它们。

我build议对两者进行sorting,并进行逐个元素的比较。

 data.OrderBy(x => x).SequenceEqual(otherData.OrderBy(x => x)) 

我不确定OrderBy的执行速度有多快,但是如果它是O(n log n)sorting就像你期望的那样,总algorithm也是O(n log n)。

对于某些数据情况,可以通过使用OrderBy的自定义实现来改进,例如对于O(n + k)使用计数sorting,其中k是值的范围的大小。

如果你可能有重复的(或者如果你想要一个更好的更长的列表的解决scheme),我会尝试这样的事情:

 static bool IsSame<T>(IEnumerable<T> set1, IEnumerable<T> set2) { if (set1 == null && set2 == null) return true; if (set1 == null || set2 == null) return false; List<T> list1 = set1.ToList(); List<T> list2 = set2.ToList(); if (list1.Count != list2.Count) return false; list1.Sort(); list2.Sort(); return list1.SequenceEqual(list2); } 

更新:哎呀,你们是对的 – 下面的Except()解决scheme在过马路之前需要两种方式。 而且对于更长的名单来说,它已经糟透了。 忽略下面的build议! 🙂

这是一个简单的方法来做到这一点。 请注意,这假设列表没有重复。

 bool same = data.Except (otherData).Count() == 0; 

我知道这是一个老问题,但这是另一种方式

 IEnumerable<int> data = new[] { 3, 5, 6, 9 }; IEnumerable<int> otherData = new[] { 6, 5, 9, 3 }; data = data.OrderBy(d => d); otherData = otherData.OrderBy(d => d); data.Zip(otherData, (x, y) => Tuple.Create(x, y)).All(d => d.Item1 == d.Item2); 
  1. 首先,检查长度。 如果它们不同,那么这些集合是不同的。
  2. 你可以做data.Intersect(otherData); ,并检查长度是否相同。
  3. 或者,简化sorting集合,并遍历它们。

这应该有所帮助:

  IEnumerable<int> data = new []{ 3,5,6,9 }; IEnumerable<int> otherData = new[] {6, 5, 9, 3}; if(data.All(x => otherData.Contains(x))) { //Code Goes Here } 

首先检查两个数据集合是否具有相同数量的元素,并检查一个集合中的所有元素是否在另一个集合中呈现

  IEnumerable<int> data = new[] { 3, 5, 6, 9 }; IEnumerable<int> otherData = new[] { 6, 5, 9, 3 }; bool equals = data.Count() == otherData.Count() && data.All(x => otherData.Contains(x));