【问题标题】:Using Linq Except with two lists of int arrays将 Linq except 与两个 int 数组列表一起使用
【发布时间】:2016-07-15 00:14:42
【问题描述】:

是否可以将 except 与两个 int 数组列表一起使用,如下所示:

List<int[]> a = new List<int[]>(){ new int[]{3,4,5}, new int[]{7,8,9}, new int[]{10,11,12}  };

List<int[]> b = new List<int[]>(){ new int[]{6,7,9}, new int[]{3,4,5}, new int[]{10,41,12}  };

var c = a.Except(b);

并期望 {3,4,5} 不存在可枚举的 c?当然我试过了,这个不起作用。有没有像Except一样有效的解决方案?或者更好、更快?

【问题讨论】:

    标签: c# arrays linq except


    【解决方案1】:

    在 .NET 中,只有当它们是完全相同的数组对象时,数组才等于另一个数组。所以两个具有相同内容的不同数组不被认为是相等的:

    int[] x = new int[] { 1, 2 };
    int[] y = new int[] { 1, 2 };
    Console.WriteLine(x == y); // false
    

    为了根据内容检查是否相等,可以使用Enumerable.SequenceEqual

    Console.WriteLine(x.SequenceEqual(y)); // true
    

    当然,在尝试使用Enumerable.Except 时,这对您没有直接帮助,因为默认情况下,它将使用仅检查相等性的默认相等比较器(并且因为每个数组都不等于除自身之外的所有其他数组......) .

    所以解决方案是use the other overload,并提供一个自定义IEqualityComparer,它根据数组的内容比较数组。

    public class IntArrayEqualityComparer : IEqualityComparer<int[]>
    {
        public bool Equals(int[] a, int[] b)
        {
            return a.SequenceEqual(b);
        }
    
        public int GetHashCode(int[] a)
        {
            return a.Sum();
        }
    }
    

    不幸的是,仅仅委托给SequenceEqual 是不够的。我们还必须提供一个GetHashCode 实现才能使其工作。作为一个简单的解决方案,我们可以在这里使用数组中数字的总和。通常,我们希望提供一个强大的散列函数,它可以说明很多关于内容的信息,但由于我们只将这个散列函数用于Except 调用,所以我们可以在这里使用一些简单的东西。 (一般来说,我们也希望避免从可变对象创建哈希值)

    当使用那个相等比较器时,我们正确地过滤掉了重复的数组:

    var c = a.Except(b, new IntArrayEqualityComparer());
    

    【讨论】:

    • 感谢您的解释和有效的解决方案!
    【解决方案2】:

    这是因为 int 数组的默认 EqualityComparer 对具有相同值的数组返回 false:

    int[] a1 = { 1, 2, 3 };
    int[] a2 = { 1, 2, 3 };
    var ec = EqualityComparer<int[]>.Default;
    Console.WriteLine(ec.Equals(a1, a2));//result is false
    

    您可以通过实现自己的 EqualityComparer 并将其实例传递给 except 方法 (see documentation) 来修复它。

    您还可以阅读 C# here 中的数组比较。

    【讨论】:

    • 感谢提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2016-09-19
    • 1970-01-01
    • 2018-10-09
    相关资源
    最近更新 更多