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 #?
Vous pouvez utiliser SequenceEqual . Cela fonctionne pour tout IEnumerable<T>
, pas seulement les tableaux.
Utilisez 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
Vous pouvez également utiliser les nouvelles interfaces à partir de .NET 4.0 pour les tableaux (et les nuplets): 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
}
Pour .NET 4.0 et les versions ultérieures, vous pouvez comparer des éléments de tableaux ou de nuplets en utilisant StructuralComparisons type:
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));
SequenceEqual
ne retournera vrai que si deux conditions sont remplies.
Si vous voulez seulement vérifier s’ils contiennent les mêmes éléments quelle que soit leur ordre et que votre problème est du type
Valeurs2 contient-il toutes les valeurs contenues dans valeurs1?
vous pouvez utiliser la méthode d'extension LINQ Enumerable.Except
et ensuite vérifier si le résultat a une valeur quelconque. Voici un exemple
int[] 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, si vous exécutez votre code comme ceci
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, donc j'utilise cette méthode.
Pour les tests unitaires, vous pouvez utiliser CollectionAssert.AreEqual
au lieu de Assert.AreEqual
.
C'est probablement le moyen le plus simple.
Si vous souhaitez gérer les entrées null
avec élégance 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;
return array1.Count() == array2.Count() && !array1.Except(array2).Any();
}
}
Le code de test ressemble à:
class Program
{
static void Main(string[] args)
{
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = new int[] { 3, 2, 1 };
int[] a3 = new int[] { 1, 3 };
int[] a4 = null;
int[] a5 = null;
int[] a6 = new int[0];
Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
Console.WriteLine(a4.ItemsEqual(a5)); // Output: True. No Exception.
Console.WriteLine(a4.ItemsEqual(a3)); // Output: False. No Exception.
Console.WriteLine(a5.ItemsEqual(a6)); // Output: False. No Exception.
}
}
Pour certaines applications peut être mieux:
string.Join("", arr1) == string.Join("", arr2)
Cette solution LINQ fonctionne, mais vous ne savez pas comment elle se compare en termes de performances à SequenceEquals. Mais il gère différentes longueurs de tableau et le .All se terminera 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)
);
comparer élémentairement? 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.
(cela combine deux exemples à partir de exemples Linq du développeur MSDN )
En supposant que l'égalité des tableaux signifie que les deux tableaux ont des éléments égaux à des index égaux, il existe le SequenceEqual
answer et le IStructuralEquatable
answer .
Mais les deux ont des inconvénients, en termes de performances.
SequenceEqual
l'implémentation actuelle ne sera pas raccourcie lorsque les tableaux auront des longueurs différentes. Elle peut donc en énumérer un entièrement, en comparant chacun de ses éléments.
IStructuralEquatable
n'est pas générique et peut entraîner la mise en boîte de chaque valeur comparée. De plus, il n’est pas très simple à utiliser et appelle déjà à coder certaines méthodes d’aide qui le cachent.
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] != second[i])
return false;
}
return true;
Mais bien sûr, ce n’est pas non plus une "méthode magique" de vérification de l’égalité des tableaux.
Donc, actuellement, non, il n'y a pas vraiment d'équivalent de Java Arrays.equals()
en .Net.
Je l'ai fait dans les studios visuels et cela a fonctionné parfaitement; comparer les 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 chiffres correspondants sont 7 Les nombres non correspondants sont 3