Ho due array. Ad esempio:Test dell'uguaglianza degli array in 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};
Qual è il modo migliore per determinare se hanno gli stessi elementi?
Ho due array. Ad esempio:Test dell'uguaglianza degli array in 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};
Qual è il modo migliore per determinare se hanno gli stessi elementi?
Utilizzando LINQ è possibile implementare espressamente e 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;
Grazie per questo snippet di codice. Funziona come un fascino per il mio scenario !! – SudheerKovalam
Trovo che questo sia molto più lento del semplice fare un ciclo e confrontare ogni elemento.Il ciclo potrebbe non essere bello ma molto, molto più veloce. –
Non ne sono sicuro. Per quanto ne so, i LINQ-to-Objects generano tabelle hash intermedie per il loop su join che sono molto più veloci di un ciclo diretto. –
Ho trovato la soluzione dettagliata here per essere un modo molto pulito, anche se un po 'prolisso per alcune persone.
La cosa migliore è che funziona anche per altri IEnumerables.
Quel collegamento descrive SequenceEqual (in .NET 3.5) e restituirà false su questi dati poiché sono in un ordine diverso. –
Per riferimento, sarebbe (usando i metodi di estensione) bool areEqual = array1.SequenceEqual (array2); –
I valori saranno sempre univoci? Se è così, come circa (dopo aver controllato uguale lunghezza):
var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);
marc, potrei anche confrontare tramite 'IStructuralEquatable' (tuples and array). Quindi, quando dovrei scegliere 'IStructuralEquatable' vs' SequenceEqual'? –
Non è 'set.SetEquals (array2)' più leggibile? – nawfal
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
Si potrebbe anche usare SequenceEqual
, purché gli oggetti IEnumerable sono ordinati per primi
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));
sì, ordina/ordina poi SequenceEqual –
Adottare estensione (che sono di nuovo in 3.0). Se la lunghezza dell'intersezione dei due array è uguale a quella della loro unione, allora gli array sono uguali.
bool equals = arrayA.Intersect(arrayB).Count() == arrayA.Union(arrayB).Count()
Succinto.
Per l'approccio più efficiente (Reflectored dal codice Microsoft), si veda la domanda Stack Overflow Comparing two collections for equality irrespective of the order of items in them.
Framework 4.0 introdotto interfaccia IStructuralEquatable che aiuta a confrontare tipi come array o tuple:
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
}
}
Ciò verifica che ogni array contiene gli stessi valori in ordine.
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;
}
sono effettivamente fare con i numeri o è che solo per l'esempio? – mmcdole
Si può usare invece una lista (ha già il metodo Contains)? –
@ed non si trattava di un semplice contiene, ma la determinazione di entrambi gli array ha gli stessi elementi, rileggere la domanda e vedere le risposte :) – eglasius