在Java中,Arrays.equals()
允许轻松比较两个基本数组的内容(重载适用于所有基本类型)。
C#中有这样的事情吗?有什么“神奇”的方法可以比较C#中两个数组的内容?
在Java中,Arrays.equals()
允许轻松比较两个基本数组的内容(重载适用于所有基本类型)。
C#中有这样的事情吗?有什么“神奇”的方法可以比较C#中两个数组的内容?
Answers:
您可以使用Enumerable.SequenceEqual
。这适用于任何IEnumerable<T>
数组,而不仅仅是数组。
SequenceEqual
可能不是一个明智的选择,因为它的当前实现可能会完全枚举其来源之一(如果它们仅在长度上有所不同)。使用数组,我们可以Length
首先检查相等性,以避免为了最终yield枚举不同长度的数组false
。
Enumerable.SequenceEqual
在LINQ中使用。
int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };
Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true
new int[] {1}.SequenceEquals(null) == false
同样对于数组(和元组),您可以使用.NET 4.0中的新接口:IStructuralComparable和IStructuralEquatable。使用它们,您不仅可以检查数组的相等性,还可以比较它们。
static class StructuralExtensions
{
public static bool StructuralEquals<T>(this T a, T b)
where T : IStructuralEquatable
{
return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
}
public static int StructuralCompare<T>(this T a, T b)
where T : IStructuralComparable
{
return a.CompareTo(b, StructuralComparisons.StructuralComparer);
}
}
{
var a = new[] { 1, 2, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.Equals(b)); // False
Console.WriteLine(a.StructuralEquals(b)); // True
}
{
var a = new[] { 1, 3, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.StructuralCompare(b)); // 1
}
a.StructuralCompare(b)
?
对于.NET 4.0及更高版本,您可以使用StructuralComparisons类型比较数组或元组中的元素:
object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };
Console.WriteLine (a1 == a2); // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2)); // False (because arrays is reference types)
IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer));
SequenceEqual
仅在满足两个或两个条件时才会返回true。
如果您只想检查它们是否包含相同的元素,而不管它们的顺序如何,而您的问题属于此类
值2是否包含值1中包含的所有值?
您可以使用LINQ扩展方法Enumerable.Except
,然后检查结果是否有任何值。这是一个例子
int[] values1 = { 1, 2, 3, 4 };
int[] values2 = { 1, 2, 5 };
var result = values1.Except(values2);
if(result.Count()==0)
{
//They are the same
}
else
{
//They are different
}
而且,通过使用此选项,您也可以自动获得不同的商品。两只鸟和一块石头。
请记住,如果您像这样执行代码
var result = values2.Except(values1);
您会得到不同的结果。
就我而言,我有一个数组的本地副本,想检查是否已从原始数组中删除了任何内容,因此我使用了此方法。
如果您希望适当地处理null
输入,而忽略项目的顺序,请尝试以下解决方案:
static class Extensions
{
public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
{
if (array1 == null && array2 == null)
return true;
if (array1 == null || array2 == null)
return false;
return array1.Count() == array2.Count() && !array1.Except(array2).Any();
}
}
测试代码如下:
class Program
{
static void Main(string[] args)
{
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = new int[] { 3, 2, 1 };
int[] a3 = new int[] { 1, 3 };
int[] a4 = null;
int[] a5 = null;
int[] a6 = new int[0];
Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
Console.WriteLine(a4.ItemsEqual(a5)); // Output: True. No Exception.
Console.WriteLine(a4.ItemsEqual(a3)); // Output: False. No Exception.
Console.WriteLine(a5.ItemsEqual(a6)); // Output: False. No Exception.
}
}
a1 = { 1, 1 }
和a2 = { 1, 2 }
,则第一个测试返回错误的结果。返回声明应为return array1.Count() == array2.Count() && !array1.Except(array2).Any() && !array2.Except(array1).Any();
这种LINQ解决方案有效,但不确定其性能如何与SequenceEquals比较。但是它将处理不同的数组长度,并且.All将在不迭代整个数组的情况下在不相等的第一项上退出。
private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2)
=>
ReferenceEquals(arr1, arr2) || (
arr1 != null && arr2 != null &&
arr1.Count == arr2.Count &&
arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i)
);
逐元素比较?关于什么
public void Linq78a()
{
int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p);
if (!bb) Console.WriteLine("Lists are equal (bb)");
else Console.WriteLine("Lists are not equal (bb)");
}
将(a == b)条件替换为要在a和b中进行比较的任何内容。
(这结合了来自MSDN开发人员Linq示例的两个示例)
true
)和null
数组(将崩溃)。
我在视觉工作室做的,效果很好。用短代码比较每个索引的数组。
private void compareButton_Click(object sender, EventArgs e)
{
int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 };
int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 };
int correctAnswers = 0;
int wrongAnswers = 0;
for (int index = 0; index < answer.Length; index++)
{
if (answer[index] == exam[index])
{
correctAnswers += 1;
}
else
{
wrongAnswers += 1;
}
}
outputLabel.Text = ("The matching numbers are " + correctAnswers +
"\n" + "The non matching numbers are " + wrongAnswers);
}
输出将是; 匹配数字为7非匹配数字为3
null
将崩溃),并且它执行的操作超出了OP的要求。他只要求知道平等,而不计算有多少项不同或匹配。
假设数组相等意味着两个数组在相等的索引处具有相等的元素,则存在SequenceEqual
答案和IStructuralEquatable
答案。
但是两者都有缺点,从性能角度来看。
SequenceEqual
当数组具有不同的长度时,当前的实现不会捷径,因此可以比较它们的每个元素来完整地枚举其中一个。
IStructuralEquatable
不是通用的,可能会引起每个比较值的装箱。而且,它并不是很简单易用,并且已经要求对一些辅助方法进行编码以将其隐藏起来。
在性能方面,使用类似以下的方法可能更好:
bool ArrayEquals<T>(T[] first, T[] second)
{
if (first == second)
return true;
if (first == null || second == null)
return false;
if (first.Length != second.Length)
return false;
for (var i = 0; i < first.Length; i++)
{
if (first[i] != second[i])
return false;
}
return true;
}
但是,当然,这也不是检查数组相等性的“神奇方法”。
因此,目前还没有,Arrays.equals()
.Net中没有真正等同于Java 的产品。
null
。你想说啥?