J'ai deux tableaux. Par exemple:
int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};
Quel est le meilleur moyen de déterminer s’ils ont les mêmes éléments?
En utilisant LINQ vous pouvez l’implémenter de manière expressive et performante:
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;
Vous pouvez également utiliser SequenceEqual
, à condition que les objets IEnumerable soient 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));
Les valeurs seront-elles toujours uniques? Si oui, que diriez-vous (après vérification de la longueur égale):
var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);
Pour une approche plus efficace ( Reflectored à partir du code Microsoft), voir Question sur le dépassement de capacité Comparaison de deux collections pour l’égalité, quel que soit l’ordre de leurs éléments.
Utilisez les méthodes d'extension (qui sont nouvelles dans la version 3.0). Si la longueur de l'intersection des deux tableaux est égale à celle de leur union, les tableaux sont égaux.
bool equals = arrayA.Intersect(arrayB).Count() == arrayA.Union(arrayB).Count()
Succinct.
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
Framework 4.0 introduit l'interface IStructuralEquatable qui permet de comparer des 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());
J'ai trouvé la solution détaillée ici être un moyen très propre, bien qu'un peu prolixe pour certaines personnes.
La meilleure chose à faire est que cela fonctionne également pour d'autres IEnumerables.
Bien sûr, il existe de nombreuses façons de comparer des tableaux basés sur la structure. Pour ajouter plus aux réponses ci-dessus, vous pouvez écrire vos propres comparateurs personnalisés. Supposons que vous souhaitiez vérifier si les deux tableaux contiennent des éléments pairs: vous définissez votre comparaison en fonction des règles de gestion de votre application. C'est pourquoi elle est si subjective.
Voici une façon de le faire, en écrivant votre propre comparateur. Veuillez noter que la méthode GetHashCode () n’a que peu d’importance et que vous devez écrire votre logique d’égalité personnalisée, en vous basant sur le comportement par défaut (comparer les types de référence) .equals () vous donnera des informations différentes. résultats si vous utilisez une autre collection pour contenir les tableaux et que nous disons que ces 2 tableaux contiennent des nombres pairs et sont donc égaux, mais nous enfreignons la règle qui "Si deux valeurs x et y sont égales, elles DOIVENT avoir le même hashcode ". Ne vous inquiétez pas trop ici car nous comparons des nombres entiers. Cela dit, voici l'exemple:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp5
{
class EvenComparer : EqualityComparer<int>
{
public override bool Equals(int x, int y)
{
if((x % 2 == 0 && y % 2 == 0))
{
return true;
}
return false;
}
public override int GetHashCode(int obj)
{
return obj.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
//If you want to check whether the arrays are equal in the sense of containing the same elements in the same order
int[] Array1 = { 2, 4, 6};
int[] Array2 = {8, 10, 12 };
string[] arr1 = { "Jar Jar Binks", "Kill! Kill!", "Aaaaargh!" };
string[] arr2 = { "Jar Jar Binks", "Kill! Kill!", "Aaaaargh!" };
bool areEqual = (arr1 as IStructuralEquatable).Equals(arr2, StringComparer.Ordinal);
bool areEqual2 = (Array1 as IStructuralEquatable).Equals(Array2, new EvenComparer());
Console.WriteLine(areEqual);
Console.WriteLine(areEqual2);
Console.WriteLine(Array1.GetHashCode());
Console.WriteLine(Array2.GetHashCode());
}
}
}
Après avoir lu les réponses, je me rends compte que personne n’a précisé qu’il fallait inclure le
using System.Collections;
ou vous obtiendrez une instruction using manquante ou une erreur de référence Assembly pour l’utilisation de l’interface IStructuralEquatable.
J'espère que ça aidera quelqu'un un jour
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;
}