71

我需要确定两组是否包含完全相同的元素。排序无关紧要。

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

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

一组不能包含任何不在另一组中的元素。

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

4

7 回答 7

122

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

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

否则,您最好的选择可能是以相同的方式对两个序列进行排序并SequenceEqual用于比较它们。

于 2009-11-04T12:06:39.670 回答
48

我建议对两者进行排序,并进行逐个元素的比较。

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

我不确定实现的速度有多快OrderBy,但如果它是 O(n log n) 排序,就像你期望的那样,总算法也是 O(n log n)。

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

于 2009-11-04T12:05:18.940 回答
6

如果您可能有重复项(或者如果您想要一个对较长列表表现更好的解决方案),我会尝试这样的事情:

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;
于 2009-11-04T12:02:42.907 回答
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);
于 2015-08-21T18:39:28.030 回答
0
  1. 首先,检查长度。如果它们不同,则集合不同。
  2. 你可以做data.Intersect(otherData);,并检查长度是否相同。
  3. 或者,对集合进行简单排序,然后遍历它们。
于 2009-11-04T12:03:02.110 回答
-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));
于 2014-11-15T20:24:58.023 回答
-2

这应该有助于:

    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
    }
于 2009-11-04T12:02:18.120 回答