web-dev-qa-db-ja.com

C#で配列を比較する方法は?

可能性のある複製:
C#で配列を比較する最も簡単な方法

C#で2つの配列を比較するにはどうすればよいですか?

次のコードを使用しますが、結果はfalseです。私はそれが真実であることを期待していました。

Array.Equals(childe1,grandFatherNode);
95
mahdi

System.LinqでEnumerable.SequenceEqual()を使用して、配列の内容を比較できます。

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

オブジェクト参照を比較していますが、それらは同じではありません。配列の内容を比較する必要があります。

.NET2ソリューション

オプションは、配列要素を繰り返し処理し、各要素に対してEquals()を呼び出します。配列要素が同じオブジェクト参照でない場合、配列要素のEquals()メソッドをオーバーライドする必要があることに注意してください。

別の方法は、この汎用メソッドを使用して2つの汎用配列を比較することです。

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;

    EqualityComparer<T> 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を使用できる場合は SequenceEqual を使用します(.NET Framework> = 3.5)

36
Daniel Peñalba

Equalsクラスには静的なArrayメソッドがないため、実際に使用しているのはObject.Equalsであり、2つのオブジェクト参照が同じオブジェクトを指しているかどうかを判断します。

配列に同じアイテムが同じ順序で含まれているかどうかを確認する場合は、SequenceEquals拡張メソッドを使用できます。

childe1.SequenceEqual(grandFatherNode)

編集:

SequenceEqualsを多次元配列で使用するには、拡張機能を使用して列挙します。以下は、2次元配列を列挙する拡張機能です。

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を超える場合、その次元数をサポートする拡張機能が必要になります。次元数が異なる場合、可変数の次元をループするにはもう少し複雑なコードが必要です。

もちろん、配列の内容を比較する前に、まず配列の次元数と次元のサイズが一致することを確認します。

編集2:

RobertSが指摘したように、OfType<T>メソッドを使用して配列をフラット化できることがわかりました。当然、すべてのアイテムを実際に同じタイプにキャストできる場合にのみ機能しますが、通常は、とにかくそれらを比較できる場合に当てはまります。例:

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

Array.Equalsは参照ではなく、その内容を比較しています:

現在、2つの配列を=演算子で比較する場合、実際にはSystem.Objectの=演算子を使用しています。これはインスタンスのみを比較します。 (つまり、これは参照の等価性を使用するため、両方の配列がまったく同じインスタンスを指している場合にのみ真になります)

ソース

配列のcontentsを比較する場合は、配列をループして要素を比較する必要があります。

同じブログ投稿には、これを行う方法の例があります。

7
ChrisF

Equalsメソッドは参照比較を行います-配列がdifferentオブジェクトの場合、これは実際にfalseを返します。

配列に同じ値が(同じ順序で)含まれているかどうかを確認するには、それらの値を反復処理し、それぞれの等価性をテストする必要があります。

1
Oded

Array.Equals()は、同じインスタンスのみをテストするようです。

値を比較するメソッドはないようですが、非常に簡単に記述できます。

長さを比較するだけで、等しくない場合はfalseを返します。それ以外の場合は、配列内の各値をループして、それらが一致するかどうかを判断します。

0
Jonathan Wood