En Java, Arrays.equals()
permet de comparer facilement le contenu de deux tableaux de base (des surcharges sont disponibles pour tous les types de base).
Existe-t-il une telle chose en C #? Existe-t-il un moyen "magique" de comparer le contenu de deux tableaux en C #?
Réponses:
Vous pourriez utiliser
Enumerable.SequenceEqual
. Cela fonctionne pour tousIEnumerable<T>
, pas seulement pour les tableaux.la source
SequenceEqual
peut ne pas être un bon choix en termes de performances, car son implémentation actuelle peut énumérer complètement l'une de ses sources si elles ne diffèrent que par la longueur. Avec les tableaux, nous pourrions d'abord vérifier l'Length
égalité, afin d'éviter d'énumérer des tableaux de différentes longueurs juste pour finir par céderfalse
.Utiliser
Enumerable.SequenceEqual
dans LINQ .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
la source
new int[] {1}.SequenceEquals(null) == false
Pour les tableaux (et les tuples), vous pouvez également utiliser de nouvelles interfaces de .NET 4.0: IStructuralComparable et IStructuralEquatable . En les utilisant, vous pouvez non seulement vérifier l'égalité des tableaux, mais aussi les comparer.
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 }
la source
a.StructuralCompare(b)
?Pour .NET 4.0 et supérieur, vous pouvez comparer des éléments dans un tableau ou des tuples en utilisant le type StructuralComparisons :
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));
la source
SequenceEqual
ne retournera vrai que si deux conditions ou remplies.Si vous voulez seulement vérifier s'ils contiennent les mêmes éléments quel que soit leur ordre et que votre problème est du type
vous pouvez utiliser la méthode d'extension LINQ
Enumerable.Except
, puis vérifier si le résultat a une valeur. Voici un exempleint[] values1 = { 1, 2, 3, 4 }; int[] values2 = { 1, 2, 5 }; var result = values1.Except(values2); if(result.Count()==0) { //They are the same } else { //They are different }
Et aussi en utilisant cela, vous obtenez automatiquement les différents éléments. Deux oiseaux avec une pierre.
Gardez à l'esprit que si vous exécutez votre code de cette manière
var result = values2.Except(values1);
vous obtiendrez des résultats différents.
Dans mon cas, j'ai une copie locale d'un tableau et je veux vérifier si quelque chose a été supprimé du tableau d'origine, j'utilise donc cette méthode.
la source
SequenceEqual
.Si vous souhaitez gérer les
null
entrées correctement et ignorer l'ordre des éléments, essayez la solution suivante:static class Extensions { public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2) { if (array1 == null && array2 == null) return true; if (array1 == null || array2 == null) return false; if (array1.Count() != array2.Count()) return false; return !array1.Except(array2).Any() && !array2.Except(array1).Any(); } }
Le code de test ressemble à:
public static void Main() { int[] a1 = new int[] { 1, 2, 3 }; int[] a2 = new int[] { 3, 2, 1 }; int[] a3 = new int[] { 1, 3 }; Console.WriteLine(a1.ItemsEqual(a2)); // Output: True. Console.WriteLine(a2.ItemsEqual(a3)); // Output: False. Console.WriteLine(a3.ItemsEqual(a2)); // Output: False. int[] a4 = new int[] { 1, 1 }; int[] a5 = new int[] { 1, 2 }; Console.WriteLine(a4.ItemsEqual(a5)); // Output: False Console.WriteLine(a5.ItemsEqual(a4)); // Output: False int[] a6 = null; int[] a7 = null; int[] a8 = new int[0]; Console.WriteLine(a6.ItemsEqual(a7)); // Output: True. No Exception. Console.WriteLine(a8.ItemsEqual(a6)); // Output: False. No Exception. Console.WriteLine(a7.ItemsEqual(a8)); // Output: False. No Exception. }
la source
a1 = { 1, 1 }
eta2 = { 1, 2 }
, alors le premier test renvoie le mauvais résultat. La déclaration de retour devrait êtrereturn array1.Count() == array2.Count() && !array1.Except(array2).Any() && !array2.Except(array1).Any();
Pour les tests unitaires, vous pouvez utiliser à la
CollectionAssert.AreEqual
place deAssert.AreEqual
.C'est probablement le moyen le plus simple.
la source
Pour certaines applications, cela peut être mieux:
string.Join(",", arr1) == string.Join(",", arr2)
la source
Cette solution LINQ fonctionne, je ne sais pas comment elle se compare en termes de performances à SequenceEquals. Mais il gère différentes longueurs de tableau et le .All se fermera sur le premier élément qui n'est pas égal sans itérer dans tout le tableau.
private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2) => ReferenceEquals(arr1, arr2) || ( arr1 != null && arr2 != null && arr1.Count == arr2.Count && arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i) );
la source
comparer par élément? qu'en est-il de
public void Linq78a() { int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p); if (!bb) Console.WriteLine("Lists are equal (bb)"); else Console.WriteLine("Lists are not equal (bb)"); }
Remplacez la condition (a == b) par tout ce que vous souhaitez comparer en a et b.
(ceci combine deux exemples des exemples Linq du développeur MSDN )
la source
true
) et lesnull
tableaux (se bloque).Je l'ai fait dans des studios visuels et cela a parfaitement fonctionné; comparaison des tableaux index par index avec ce code court.
private void compareButton_Click(object sender, EventArgs e) { int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 }; int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 }; int correctAnswers = 0; int wrongAnswers = 0; for (int index = 0; index < answer.Length; index++) { if (answer[index] == exam[index]) { correctAnswers += 1; } else { wrongAnswers += 1; } } outputLabel.Text = ("The matching numbers are " + correctAnswers + "\n" + "The non matching numbers are " + wrongAnswers); }
la sortie sera; Les numéros correspondants sont 7 Les numéros non correspondants sont 3
la source
null
tableaux (se plantera aussi), et il fait autre chose que ce que l'OP a demandé. Il a seulement demandé à connaître l'égalité, sans compter combien d'éléments diffèrent ou correspondent.En supposant que l'égalité des tableaux signifie que les deux tableaux ont des éléments égaux à des index égaux, il y a la
SequenceEqual
réponse et laIStructuralEquatable
réponse .Mais les deux ont des inconvénients, en termes de performances.
SequenceEqual
l'implémentation actuelle ne raccourcira pas lorsque les tableaux ont des longueurs différentes, et peut donc en énumérer un entièrement, en comparant chacun de ses éléments.IStructuralEquatable
n'est pas générique et peut provoquer un encadrement de chaque valeur comparée. De plus, il n'est pas très simple à utiliser et nécessite déjà de coder des méthodes d'aide pour le cacher.Il peut être préférable, en termes de performances, d'utiliser quelque chose comme:
bool ArrayEquals<T>(T[] first, T[] second) { if (first == second) return true; if (first == null || second == null) return false; if (first.Length != second.Length) return false; for (var i = 0; i < first.Length; i++) { if (!first[i].Equals(second[i])) return false; } return true; }
Mais bien sûr, ce n'est pas non plus une "manière magique" de vérifier l'égalité des tableaux.
Donc actuellement, non, il n'y a pas vraiment d'équivalent à Java
Arrays.equals()
en .Net.la source
Vous pouvez utiliser
Enumerable.Intersect
:int[] array1 = new int[] { 1, 2, 3, 4,5 }, array2 = new int[] {7,8}; if (array1.Intersect(array2).Any()) Console.WriteLine("matched"); else Console.WriteLine("not matched");
la source
Arrays.equals()
.int[] a = { 2, 1, 3, 4, 5, 2 }; int[] b = { 2, 1, 3, 4, 5, 2 }; bool ans = true; if(a.Length != b.Length) { ans = false; } else { for (int i = 0; i < a.Length; i++) { if( a[i] != b[i]) { ans = false; } } } string str = ""; if(ans == true) { str = "Two Arrays are Equal"; } if (ans == false) { str = "Two Arrays are not Equal"; } //--------------Or You can write One line of Code------------- var ArrayEquals = a.SequenceEqual(b); // returns true
la source