Alb*_*ino 6 c# linq arrays 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);
Run Code Online (Sandbox Code Playgroud)
并且考虑{3,4,5}不存在可枚举的c?当然我试过了,这个没用.有没有像Except一样高效的解决方案?或者甚至更好,更快?
在.NET中,如果数组是完全相同的数组对象,则它们只等于另一个数组.因此,具有相同内容的两个不同阵列不被视为相等:
int[] x = new int[] { 1, 2 };
int[] y = new int[] { 1, 2 };
Console.WriteLine(x == y); // false
Run Code Online (Sandbox Code Playgroud)
为了根据内容检查相等性,您可以使用Enumerable.SequenceEqual:
Console.WriteLine(x.SequenceEqual(y)); // true
Run Code Online (Sandbox Code Playgroud)
当然,要使用时,它不能帮助你直接的Enumerable.Except,因为在默认情况下将使用默认的相等比较,只有平等检查(和因为每个阵列是不相等的每一个其它阵列本身除外......).
所以解决方案是使用另一个重载,并提供一个自定义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();
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,仅仅委托SequenceEqual是不够的.我们还必须为此提供GetHashCode实现.作为一个简单的解决方案,我们可以在这里使用数组中的数字之和.通常,我们希望提供一个强大的哈希函数,它告诉了很多内容,但由于我们只使用这个哈希函数进行Except调用,我们可以在这里使用一些简单的东西.(通常,我们还希望避免从可变对象创建哈希值)
使用该相等比较器时,我们正确地过滤掉了重复的数组:
var c = a.Except(b, new IntArrayEqualityComparer());
Run Code Online (Sandbox Code Playgroud)
那是因为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
Run Code Online (Sandbox Code Playgroud)
您可以通过实现自己的EqualityComparer并将其实例传递给Except方法来修复它(请参阅文档).
您还可以在此处阅读C#中的数组比较.
| 归档时间: |
|
| 查看次数: |
1413 次 |
| 最近记录: |