我需要确定两个集合是否包含完全相同的元素。排序无关紧要。
例如,这两个数组应该被认为是相等的:
IEnumerable<int> data = new []{3, 5, 6, 9};
IEnumerable<int> otherData = new []{6, 5, 9, 3}
一组不能包含任何不在另一组中的元素。
可以使用内置查询运算符完成吗?考虑到元素的数量可以从几个到几百个,那么实现它的最有效方法是什么呢?
答案 0 :(得分:110)
如果您想将数组视为“集合”并忽略订单和重复项,则可以使用HashSet<T>.SetEquals
method:
var isEqual = new HashSet<int>(first).SetEquals(second);
否则,您最好的选择可能是以相同的方式对两个序列进行排序,并使用SequenceEqual
进行比较。
答案 1 :(得分:45)
我建议对两者进行排序,并进行逐元素比较。
data.OrderBy(x => x).SequenceEqual(otherData.OrderBy(x => x))
我不确定OrderBy
的实现有多快,但是如果它是O(n log n)排序,就像你期望总算法也是O(n log n)一样。 / p>
对于某些数据情况,您可以通过使用OrderBy的自定义实现来改进这一点,例如对O(n + k)使用计数排序,其中k是值所在的范围的大小。< / p>
答案 2 :(得分:3)
如果您可能有重复项(或者如果您想要一个对更长列表更好的解决方案),我会尝试这样的事情:
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()解决方案需要在过马路之前双向查看。对于更长的列表,它有糟糕的性能。忽略下面的建议! : - )强>
这是一种简单的方法。请注意,这假设列表没有重复。
bool same = data.Except (otherData).Count() == 0;
答案 3 :(得分:3)
这是另一种方法:
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);
答案 4 :(得分:0)
data.Intersect(otherData);
,并检查长度是否相同。答案 5 :(得分:-1)
这应该有所帮助:
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
}
答案 6 :(得分:-1)
首先检查两个数据集合是否具有相同数量的元素,并检查一个集合中的所有元素是否都显示在另一个集合中
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));