在Java中,arrays .equals()允许轻松地比较两个基本数组的内容(重载可用于所有基本类型)。
c#中有这样的东西吗?在c#中是否存在比较两个数组内容的“神奇”方法?
在Java中,arrays .equals()允许轻松地比较两个基本数组的内容(重载可用于所有基本类型)。
c#中有这样的东西吗?在c#中是否存在比较两个数组内容的“神奇”方法?
当前回答
检查这个线程的答案,它将其中一个数组转换为HashSet,并使用SetEquals与另一个数组进行比较。 但是请注意,这并不检查顺序或副本。
其他回答
同样对于数组(和元组),你可以使用。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
}
如果您不想比较顺序,但确实想比较每一项的计数,包括处理空值,那么我为此编写了一个扩展方法。
例如,它给出了以下结果:
new int?[]{ }.IgnoreOrderComparison(new int?{ }); // true
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ }); // false
new int?[]{ }.IgnoreOrderComparison(new int?{ 1 }); // false
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ 1 }); // true
new int?[]{ 1, 2 }.IgnoreOrderComparison(new int?{ 2, 1 }); // true
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ 2, 1 }); // false
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // true
new int?[]{ 1, 2, null, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // false
new int?[]{ 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // false
new int?[]{ 2, 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // true
代码如下:
public static class ArrayComparisonExtensions
{
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) =>
IgnoreOrderComparison(first, second, EqualityComparer<TSource>.Default);
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
var a = ToDictionary(first, out var firstNullCount);
var b = ToDictionary(second, out var secondNullCount);
if (a.Count != b.Count)
return false;
if (firstNullCount != secondNullCount)
return false;
foreach (var item in a)
{
if (b.TryGetValue(item.Key, out var count) && item.Value == count)
continue;
return false;
}
return true;
Dictionary<TSource, int> ToDictionary(IEnumerable<TSource> items, out int nullCount)
{
nullCount = 0;
var result = new Dictionary<TSource, int>(comparer);
foreach (var item in items)
{
if (item is null)
nullCount++;
else if (result.TryGetValue(item, out var count))
result[item] = count + 1;
else
result[item] = 1;
}
return result;
}
}
}
它只枚举每个枚举对象一次,但它确实为每个枚举对象创建了一个字典,并迭代这些字典一次。我对如何改善这一点很感兴趣。
检查这个线程的答案,它将其中一个数组转换为HashSet,并使用SetEquals与另一个数组进行比较。 但是请注意,这并不检查顺序或副本。
对于。net 4.0及更高版本,您可以通过使用structuralcompare类型比较数组或元组中的元素:
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));
可列举的使用。LINQ中的SequenceEqual。
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