C#中如何比较数组?

发布于 2024-10-07 03:04:04 字数 309 浏览 0 评论 0原文

可能的重复:
在 C# 中比较数组的最简单方法

如何比较两个数组C# 中的数组?

我使用以下代码,但其结果是错误的。我原以为这是真的。

Array.Equals(childe1,grandFatherNode);

Possible Duplicate:
Easiest way to compare arrays in C#

How can I compare two arrays in C#?

I use the following code, but its result is false. I was expecting it to be true.

Array.Equals(childe1,grandFatherNode);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

小红帽 2024-10-14 03:04:04

您可以使用 System.Linq 中的 Enumerable.SequenceEqual() 来比较数组中的内容

bool isEqual = Enumerable.SequenceEqual(target1, target2);

You can use the Enumerable.SequenceEqual() in the System.Linq to compare the contents in the array

bool isEqual = Enumerable.SequenceEqual(target1, target2);
野鹿林 2024-10-14 03:04:04

您正在比较对象引用,它们并不相同。您需要比较数组内容。

.NET2 解决方案

一个选项是迭代数组元素并为每个元素调用 Equals()。请记住,如果数组元素不是同一对象引用,则需要重写 Equals() 方法。

另一种方法是使用此通用方法来比较两个通用数组:

static bool ArraysEqual<T>(T[] a1, T[] a2)
{
    if (ReferenceEquals(a1, a2))
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    var comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < a1.Length; i++)
    {
        if (!comparer.Equals(a1[i], a2[i])) return false;
    }
    return true;
}

.NET 3.5 或更高版本的解决方案

或使用 SequenceEqual(如果 Linq 可用)(.NET Framework >= 3.5)

You're comparing the object references, and they are not the same. You need to compare the array contents.

.NET2 solution

An option is iterating through the array elements and call Equals() for each element. Remember that you need to override the Equals() method for the array elements, if they are not the same object reference.

An alternative is using this generic method to compare two generic arrays:

static bool ArraysEqual<T>(T[] a1, T[] a2)
{
    if (ReferenceEquals(a1, a2))
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    var comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < a1.Length; i++)
    {
        if (!comparer.Equals(a1[i], a2[i])) return false;
    }
    return true;
}

.NET 3.5 or higher solution

Or use SequenceEqual if Linq is available for you (.NET Framework >= 3.5)

九歌凝 2024-10-14 03:04:04

Array类中没有静态的Equals方法,所以你使用的实际上是Object.Equals,它判断两个对象引用是否相同指向同一个对象。

如果要检查数组是否包含相同顺序的相同项目,可以使用 SequenceEquals 扩展方法:

childe1.SequenceEqual(grandFatherNode)

编辑:

要将 SequenceEquals 与多维数组一起使用,您可以使用扩展来枚举它们。以下是枚举二维数组的扩展:

public static IEnumerable<T> Flatten<T>(this T[,] items) {
  for (int i = 0; i < items.GetLength(0); i++)
    for (int j = 0; j < items.GetLength(1); j++)
      yield return items[i, j];
}

用法:

childe1.Flatten().SequenceEqual(grandFatherNode.Flatten())

如果数组的维数多于二维,则需要支持该维数的扩展。如果维度数量变化,您将需要更复杂的代码来循环可变数量的维度。

当然,在比较数组的内容之前,您首先要确保数组的维数和维数大小匹配。

编辑 2:

事实证明,您可以使用 OfType 方法来展平数组,正如 RobertS 指出的那样。当然,只有当所有项目实际上都可以转换为同一类型时,这才有效,但如果您无论如何都可以比较它们,通常就是这种情况。例子:

childe1.OfType<Person>().SequenceEqual(grandFatherNode.OfType<Person>())

There is no static Equals method in the Array class, so what you are using is actually Object.Equals, which determines if the two object references point to the same object.

If you want to check if the arrays contains the same items in the same order, you can use the SequenceEquals extension method:

childe1.SequenceEqual(grandFatherNode)

Edit:

To use SequenceEquals with multidimensional arrays, you can use an extension to enumerate them. Here is an extension to enumerate a two dimensional array:

public static IEnumerable<T> Flatten<T>(this T[,] items) {
  for (int i = 0; i < items.GetLength(0); i++)
    for (int j = 0; j < items.GetLength(1); j++)
      yield return items[i, j];
}

Usage:

childe1.Flatten().SequenceEqual(grandFatherNode.Flatten())

If your array has more dimensions than two, you would need an extension that supports that number of dimensions. If the number of dimensions varies, you would need a bit more complex code to loop a variable number of dimensions.

You would of course first make sure that the number of dimensions and the size of the dimensions of the arrays match, before comparing the contents of the arrays.

Edit 2:

Turns out that you can use the OfType<T> method to flatten an array, as RobertS pointed out. Naturally that only works if all the items can actually be cast to the same type, but that is usually the case if you can compare them anyway. Example:

childe1.OfType<Person>().SequenceEqual(grandFatherNode.OfType<Person>())
困倦 2024-10-14 03:04:04

Array.Equals 正在比较引用,而不是它们的内容:

目前,当您使用 = 运算符比较两个数组时,我们实际上使用的是 System.Object 的 = 运算符,它仅比较实例。 (即,这使用引用相等,因此仅当两个数组都指向完全相同的实例时才为真)

如果您想比较数组的内容,您需要循环遍历数组并比较元素。

同一篇博客文章提供了如何执行此操作的示例。基本的实现是:

public static bool ArrayEquals<T>(T[] a, T[] b)
{
    if (a.Length != b.Length)
    {
        return false;
    }

    for (int i = 0; i < a.Length; i++)
    {
        if (!a[i].Equals(b[i]))
        {
            return false;
        }
    }

    return true;
}

尽管这会带来性能问题。添加约束:

public static bool ArrayEquals<T>(T[] a, T[] b) where T: IEquatable<T>

会改善情况,但意味着代码仅适用于实现 IEquatable 的类型。

使用 EqualityComparer.Default 的 Equal 方法而不是对类型本身调用 Equals 也可以提高性能,而不需要类型实现 IEquatable。在这种情况下,方法的主体变为:

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;

    for (int i = 0; i < a.Length; i++)
    {
        if (!comparer.Equals(a[i], b[i]))
        {
            return false;
        }
    }

Array.Equals is comparing the references, not their contents:

Currently, when you compare two arrays with the = operator, we are really using the System.Object's = operator, which only compares the instances. (i.e. this uses reference equality, so it will only be true if both arrays points to the exact same instance)

Source

If you want to compare the contents of the arrays you need to loop though the arrays and compare the elements.

The same blog post has examples of how to do this. The basic implementation is:

public static bool ArrayEquals<T>(T[] a, T[] b)
{
    if (a.Length != b.Length)
    {
        return false;
    }

    for (int i = 0; i < a.Length; i++)
    {
        if (!a[i].Equals(b[i]))
        {
            return false;
        }
    }

    return true;
}

Though this will have performance issues. Adding a constraint:

public static bool ArrayEquals<T>(T[] a, T[] b) where T: IEquatable<T>

will improve things but will mean the code only works with types that implement IEquatable.

Using EqualityComparer.Default's Equal method instead of calling Equals on the types themselves will also improve performance without requiring the type to implement IEquatable. In this case the body of the method becomes:

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;

    for (int i = 0; i < a.Length; i++)
    {
        if (!comparer.Equals(a[i], b[i]))
        {
            return false;
        }
    }
十雾 2024-10-14 03:04:04

Equals 方法进行引用比较 - 如果数组是不同对象,这确实会返回 false。

要检查数组是否包含相同的值(并且顺序相同),您需要迭代它们并测试每个值的相等性。

The Equals method does a reference comparison - if the arrays are different objects, this will indeed return false.

To check if the arrays contain identical values (and in the same order), you will need to iterate over them and test equality on each.

酒几许 2024-10-14 03:04:04

Array.Equals() 似乎只测试同一个实例。

似乎没有一种方法可以比较这些值,但它很容易编写。

只需比较长度,如果不相等,则返回 false。否则,循环遍历数组中的每个值并确定它们是否匹配。

Array.Equals() appears to only test for the same instance.

There doesn't appear to be a method that compares the values but it would be very easy to write.

Just compare the lengths, if not equal, return false. Otherwise, loop through each value in the array and determine if they match.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文