【问题标题】:How to compare arrays in C#? [duplicate]如何比较 C# 中的数组? [复制]
【发布时间】:2010-12-12 18:46:33
【问题描述】:

可能重复:
Easiest way to compare arrays in C#

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

我使用下面的代码,但它的结果是假的。我期待它是真的。

Array.Equals(childe1,grandFatherNode);

【问题讨论】:

  • 你能给我们举个例子吗?

标签: c# arrays compare


【解决方案1】:

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

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

【讨论】:

  • 很好的答案,我知道这有点晚了,但可以简化为:bool isEqual = target1.SequenceEqual(target2);
  • AMing 解决方案处理空情况(并且更“对称”)。
  • @Orace:实际上,如果任一参数为空,则 Enumerable.SequenceEqual 会给出异常。
  • Enumerable.SequenceEqual(x, y)x.SequenceEqual(y) 的行为方式相同:如果第一个或第二个集合为空,它们会抛出 ArgumentNullException。看看implementation on Reference Source
  • 快速解释一下:x.SequenceEqual 是一种扩展方法,因此它与调用Enumerable.SequenceEqual 完全相同。因此,无论您以哪种方式编写调用,有关空输入的行为都是相同的
【解决方案2】:

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

.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 或更高版本的解决方案

如果您可以使用 Linq (.NET Framework >= 3.5),请使用 SequenceEqual

【讨论】:

  • 我的数组是多维的,SequenceEqual 不适用于这种类型
  • @madhi:您可以扩展该方法以接收 T[][] 而不是 T[]。您是否考虑过将问题标记为已回答?谢谢!!
【解决方案3】:

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:

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

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

【讨论】:

  • 我的数组是多维的,这个方法对它不起作用!
  • @mahdi:您可以使用简单的扩展来使多维数组可枚举。我在上面添加了一个示例。
  • @Trisped:Flatten 方法不会创建任何新数组,它只是将数组作为一维枚举访问的一种方式。
  • @Mark:不,没有错。我在答案中明确写道:“在比较数组的内容之前,您当然会首先确保数组的维数和维数匹配。”
  • 您可以使用OfType&lt;T&gt; 来展平多维数组。无需创建新的扩展方法。
【解决方案4】:

Array.Equals 比较的是参考文献,而不是它们的内容:

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

Source

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

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

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;
        }
    }

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      似乎没有比较值的方法,但它很容易编写。

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

      【讨论】:

        猜你喜欢
        • 2013-05-10
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 2020-07-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多