137 votes

Comment comparer des tableaux en C# ?

Duplicata possible :
Le moyen le plus simple de comparer des tableaux en C#

Comment comparer deux tableaux en C# ?

J'utilise le code suivant, mais son résultat est faux. Je m'attendais à ce qu'il soit vrai.

Array.Equals(childe1,grandFatherNode);

0 votes

Pouvez-vous nous donner un exemple ?

6 votes

Comment se fait-il qu'une réponse n'ait jamais été marquée ici ?

287voto

AMing Points 1241

Vous pouvez utiliser la fonction Enumerable.SequenceEqual() de System.Linq pour comparer le contenu d'un tableau.

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

30 votes

Excellente réponse, et je sais que c'est un peu tard, mais cela pourrait être simplifié comme suit : bool isEqual = target1.SequenceEqual(target2) ;

9 votes

La solution AMing gère les cas nuls (et est plus "symétrique").

6 votes

@Orace : en fait, Enumerable.SequenceEqual donne une exception si l'un des deux arguments est nul.

48voto

Daniel Peñalba Points 8548

Vous comparez les références aux objets et ils ne sont pas identiques. Vous devez comparer le contenu des tableaux.

Solution .NET2

Une option est d'itérer à travers les éléments du tableau et d'appeler Equals() pour chaque élément. N'oubliez pas que vous devez remplacer l'option Equals() pour les éléments du tableau, s'ils ne sont pas la même référence d'objet.

Une alternative consiste à utiliser cette méthode générique pour comparer deux tableaux génériques :

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

Solution .NET 3.5 ou supérieure

Ou utilisez SéquenceEqual si Linq est disponible pour vous (.NET Framework >= 3.5)

2 votes

Mes tableaux sont multidimensionnels et SequenceEqual ne fonctionne pas pour ce type.

1 votes

@madhi : Vous pouvez étendre la méthode pour recevoir T[][] au lieu de T[]. Avez-vous pensé à marquer la question comme ayant reçu une réponse ? Merci !

25voto

Guffa Points 308133

Il n'y a pas de statique Equals dans la méthode Array donc ce que vous utilisez est en fait Object.Equals qui détermine si les deux références d'objet pointent vers le même objet.

Si vous voulez vérifier si les tableaux contiennent les mêmes éléments dans le même ordre, vous pouvez utiliser la fonction SequenceEquals méthode d'extension :

childe1.SequenceEqual(grandFatherNode)

Edit :

Pour utiliser SequenceEquals Avec les tableaux multidimensionnels, vous pouvez utiliser une extension pour les énumérer. Voici une extension pour énumérer un tableau à deux dimensions :

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

Utilisation :

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

Si votre tableau a plus de deux dimensions, vous aurez besoin d'une extension qui supporte ce nombre de dimensions. Si le nombre de dimensions varie, vous aurez besoin d'un code un peu plus complexe pour boucler un nombre variable de dimensions.

Bien entendu, vous devez d'abord vous assurer que le nombre de dimensions et la taille des dimensions des tableaux correspondent, avant de comparer le contenu des tableaux.

Edit 2 :

Il s'avère que vous pouvez utiliser le OfType<T> pour aplatir un tableau, comme l'a souligné RobertS. Naturellement, cela ne fonctionne que si tous les éléments peuvent être convertis au même type, mais c'est généralement le cas si vous pouvez les comparer de toute façon. Exemple :

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

0 votes

Mon tableau est multidimensionnel et cette méthode ne fonctionne pas sur lui !

0 votes

@mahdi : Vous pouvez utiliser une simple extension pour rendre un tableau multidimensionnel énumérable. J'ai ajouté un exemple ci-dessus.

0 votes

@Trisped : Le site Flatten ne crée pas de nouveau tableau, c'est juste un moyen d'accéder au tableau en tant qu'énumérable unidimensionnel.

13voto

ChrisF Points 74295

Array.Equals compare les références, pas leur contenu :

Actuellement, lorsque l'on compare deux tableaux avec l'opérateur =, on utilise en réalité l'opérateur = de System.Object, qui ne compare que les instances. (c'est-à-dire qu'il utilise l'égalité de référence, donc il ne sera vrai que si les deux tableaux pointent vers la même instance).

Source :

Si vous voulez comparer les contenu des tableaux, vous devez les parcourir en boucle et comparer les éléments.

Le même article de blog contient des exemples de la manière de procéder. L'implémentation de base est la suivante :

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

Bien que cela pose des problèmes de performance. Ajout d'une contrainte :

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

améliorera les choses mais signifiera que le code ne fonctionne qu'avec les types qui implémentent IEquatable .

L'utilisation de la méthode Equal de EqualityComparer.Default au lieu d'appeler Equals sur les types eux-mêmes améliorera également les performances sans exiger que le type mette en œuvre la méthode IEquatable . Dans ce cas, le corps de la méthode devient :

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

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

2voto

Oded Points 271275

Le site Equals fait une comparaison de référence - si les tableaux sont différents cela renverra en effet false.

Pour vérifier si les tableaux contiennent des valeurs identiques (et dans le même ordre), vous devrez les itérer et tester l'égalité sur chacun d'eux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X