J'ai deux tableaux. Par exemple:Test de l'égalité des tableaux en C#
int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};
Quelle est la meilleure façon de déterminer s'ils ont les mêmes éléments?
J'ai deux tableaux. Par exemple:Test de l'égalité des tableaux en C#
int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};
Quelle est la meilleure façon de déterminer s'ils ont les mêmes éléments?
En utilisant LINQ vous pouvez le mettre en œuvre expressivement et performant:
var q = from a in ar1
join b in ar2 on a equals b
select a;
bool equals = ar1.Length == ar2.Length && q.Count() == ar1.Length;
Merci pour ce petit bout de code. Fonctionne comme un charme pour mon scénario !! – SudheerKovalam
Je trouve que c'est beaucoup plus lent que de faire une boucle et de comparer chaque élément.La boucle n'est peut-être pas aussi belle, mais beaucoup plus rapide. –
Je ne suis pas sûr de ça. Pour autant que je sache, LINQ-to-Objects génère des tables de hachage intermédiaires pour boucler des jointures qui sont beaucoup plus rapides qu'une boucle droite. –
J'ai trouvé la solution détaillée here pour être très propre, bien qu'un peu verbeux pour certaines personnes.
La meilleure chose est que cela fonctionne aussi pour d'autres IEnumerables.
Ce lien décrit SequenceEqual (dans .NET 3.5), et retournera false sur ces données car elles sont dans un ordre différent. –
Pour référence, ce serait (en utilisant des méthodes d'extension) bool areEqual = array1.SequenceEqual (array2); –
Les valeurs seront-elles toujours uniques? Si oui, que diriez-vous (après vérification de longueur égale):
var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);
marc, je pourrais également comparer via 'IStructuralEquatable' (tuples et tableaux). Alors, quand devrais-je choisir 'IStructuralEquatable' vs' SequenceEqual'? –
Est-ce que 'set.SetEquals (array2)' n'est pas plus lisible? – nawfal
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
Vous pouvez également utiliser SequenceEqual
, à condition que les objets IEnumerable sont triés en premier.
int[] a1 = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] a2 = new[] { 9, 1, 4, 5, 2, 3, 6, 7, 8 };
bool equals = a1.OrderBy(a => a).SequenceEqual(a2.OrderBy(a => a));
yep, trier/commander puis SequenceEqual –
Utilisez les méthodes d'extension (qui sont nouvelles dans 3.0). Si la longueur de l'intersection des deux tableaux est égale à celle de leur union, alors les tableaux sont égaux.
bool equals = arrayA.Intersect(arrayB).Count() == arrayA.Union(arrayB).Count()
Succinct.
Pour l'approche (Reflectored à partir du code Microsoft) le plus efficace, voir Stack Overflow question Comparing two collections for equality irrespective of the order of items in them.
Framework 4.0 introduit une interface IStructuralEquatable qui permet de comparer les types tels que des tableaux ou des tuples:
class Program
{
static void Main()
{
int[] array1 = { 1, 2, 3 };
int[] array2 = { 1, 2, 3 };
IStructuralEquatable structuralEquator = array1;
Console.WriteLine(array1.Equals(array2)); // False
Console.WriteLine(structuralEquator.Equals(array2, EqualityComparer<int>.Default)); // True
// string arrays
string[] a1 = "a b c d e f g".Split();
string[] a2 = "A B C D E F G".Split();
IStructuralEquatable structuralEquator1 = a1;
bool areEqual = structuralEquator1.Equals(a2, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Arrays of strings are equal:"+ areEqual);
//tuples
var firstTuple = Tuple.Create(1, "aaaaa");
var secondTuple = Tuple.Create(1, "AAAAA");
IStructuralEquatable structuralEquator2 = firstTuple;
bool areTuplesEqual = structuralEquator2.Equals(secondTuple, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Are tuples equal:" + areTuplesEqual);
IStructuralComparable sc1 = firstTuple;
int comparisonResult = sc1.CompareTo(secondTuple, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Tuples comarison result:" + comparisonResult);//0
}
}
Cela vérifiera que chaque tableau contient les mêmes valeurs dans l'ordre.
int[] ar1 = { 1, 1, 5, 2, 4, 6, 4 };
int[] ar2 = { 1, 1, 5, 2, 4, 6, 4 };
var query = ar1.Where((b, i) => b == ar2[i]);
Assert.AreEqual(ar1.Length, query.Count());
public static bool ValueEquals(Array array1, Array array2)
{
if(array1 == null && array2 == null)
{
return true;
}
if((array1 == null) || (array2 == null))
{
return false;
}
if(array1.Length != array2.Length)
{
return false;
}
if(array1.Equals(array2))
{
return true;
}
else
{
for (int Index = 0; Index < array1.Length; Index++)
{
if(!Equals(array1.GetValue(Index), array2.GetValue(Index)))
{
return false;
}
}
}
return true;
}
Êtes-vous réellement chiffrées ou est-ce juste pour l'exemple? – mmcdole
Pouvez-vous utiliser une liste à la place (a déjà la méthode Contains)? –
@ed il ne s'agissait pas d'un simple contenant, mais déterminer les deux tableaux a les mêmes éléments, relire la question et voir les réponses :) – eglasius