C#:比较两个IEnumerables的内容

Svi*_*ish 38 c# linq

是否有一个内置的linq方法的东西,我可以用来找出两个序列是否包含相同的项目,而不考虑订单?

例如:

{1, 2, 3} == {2, 1, 3}
{1, 2, 3} != {2, 1, 3, 4}
{1, 2, 3} != {1, 2, 4}
Run Code Online (Sandbox Code Playgroud)

你有SequenceEquals,但是我必须首先对两个序列进行排序,不是吗?

lep*_*pie 41

有很多方法.假设A和B是IEnumerable.

!A.Except(B).Any() && !B.Except(A).Any()
A.Count() == B.Count() && A.Intersect(B).Count() == B.Count()
etc
Run Code Online (Sandbox Code Playgroud)

  • query.Count()== 0与!query.Any()相同,但any调用更快,因为它不评估整个列表. (9认同)
  • 此代码仅在序列为集合时有效,即其中没有重复项 (6认同)

Jon*_*nna 10

如果您不关心重复项(即您认为{1, 2, 3}等于{1, 2, 3, 2}),则:

new HashSet<int>(A).SetEquals(B)
Run Code Online (Sandbox Code Playgroud)

(或任何类型是元素类型而不是int)。

除此以外:

public static bool SequenceEqualUnordered<T>(IEnumerable<T> first, IEnumerable<T> second)
{
    if (first == null)
        return second == null; // or throw if that's more appropriate to your use.
    if (second == null)
        return false;   // likewise.
    var dict = new Dictionary<T, int>(); // You could provide a IEqualityComparer<T> here if desired.
    foreach(T element in first)
    {
        int count;
        dict.TryGetValue(element, out count);
        dict[element] = count + 1;
    }
    foreach(T element in second)
    {
        int count;
        if (!dict.TryGetValue(element, out count))
            return false;
        else if (--count == 0)
            dict.Remove(element);
        else
            dict[element] = count;
    }
    return dict.Count == 0;
}
Run Code Online (Sandbox Code Playgroud)

记录第一个序列中的每个元素,然后根据它检查第二个元素。如果第二个序列中的元素过多,则可以返回 false,否则,如果计数字典中没有任何内容,则它们是相等的,如果还有任何元素,则返回 false。

不是两种 O(n log n) 类型的使用OrderBy()后跟 O(n) 比较,而是使用 O(n) 操作构建计数集,并对其进行 O(n) 检查。


小智 9

有两个IEnumerables(A和B):

bool equal = (A.Count() == B.Count() && (!A.Except(B).Any() || !B.Except(A).Any()))
Run Code Online (Sandbox Code Playgroud)

我认为这比Except(A).Count更好,因为不会评估整个Excep.只要在"除外"中找到一个元素,它就会停止.使用Count,可以评估整个Except.除此之外,我们可以避免对这些代价高昂的评估,除非首先检查Count属性.如果计数不相等,那么我们检查Excepts.

  • `Except()` 之间的 `||` 应该是 `&amp;&amp;`,正如 [answer](/sf/answers/44119491/) 所建议的那样。否则,以下情况也成立:“{1,2,3} == {1,2,1}”。我不确定它是否正确 - 至少不适合我的情况:)。 (2认同)