2012-06-12 11 views
21

Come confrontare due stringhe di array utilizzando C# .net? Ad esempio:Come ottengo le differenze tra due array di stringhe in C#?

string[] com1 = { "COM6", "COM7" }; 
string[] com2 = { "COM6", "COM7","COM8" }; 

Qui COM1 e COM2 sono stringa Array. Risultato: COM8. Come raggiungere questo?

+9

sarebbe davvero aiutare se dovessi dare più dettagli sul confronto che vuoi fare. Ad esempio, consideri importante l'ordine? Astuccio? Che dire se un elemento si verifica in 'com1' ma non in' com2'? –

risposta

6

penso che questo la strada più breve per risolvere questo

foreach (string com in com2) 
{ 
    if (!com1.Contains(com)) 
    { 
     MessageBox.Show(com); 
    } 
} 
17

Utilizzando il Linq Except extension:

IEnumerable<string> result = com2.Except(com1); 
// result: { "COM8" } 
+0

Suggerimento: cambia 'risultato' a' tranne' (o viceversa) – Default

49

Sembra che si desidera tutto in array2tranne cosa c'è in array1:

var onlyInArray2 = array2.Except(array1); 

Naturalmente, se si anche voluto sapere che cosa era solo in array1 si potrebbe usare:

var onlyInArray1 = array1.Except(array2); 

(Tutto ciò richiede .NET 3.5 o versione successiva o un'implementazione LINQ to Objects alternativa come LINQBridge.)

Suppongo che l'ordine non sia importante quando si calcolano le differenze - Except è un operatore basato su set, quindi si presuppone che si tratti di collezioni come insiemi.

Nota che Except restituisce solo un IEnumerable<T> - se si desidera che i risultati come array, è necessario chiamare ToArray:

var onlyInArray2 = array2.Except(array1).ToArray(); 
var onlyInArray1 = array1.Except(array2).ToArray(); 

Se si desidera che la differenza simmetrica, cioè vi interessa soltanto che i valori sono in un singolo array, invece di che serie sono venuti, è possibile utilizzare:

var onlyInOneArray = array1.Union(array2).Except(array1.Intersect(array2)); 

o si potrebbe usare HashSet direttamente:

In tutti questi, l'ordine risultante non è definito, sebbene nella pratica Except manterrà l'ordine originale del primo argomento. Anche se questo è strettamente un dettaglio di implementazione, penso che sia molto improbabile che cambi.

Come gli altri operatori set a base di LINQ, Except torneranno solo una volta ogni elemento - quindi se COM8 apparso due volte in array2, sembrerebbe solo una volta nel risultato.

+1

Sua Maestà Jon, aggiunge sempre qualcosa di più ;-) – aleroot

+2

Penso che con le tue migliori risposte qui potresti scrivere un altro Libro ... Comprerò di sicuro! – aleroot

2

Se si desidera tutto ciò che è in una sola lista, ma non entrambi, in una sola espressione, è possibile utilizzare Union, IntersecteExcept:

var inOnlyOneArray = array1.Union(array2).Except(array1.Intersect(array2)); 
+0

+, quello è intelligente! –

1

Come altri hanno già detto, il metodo di estensione Except è sicuramente il modo di andare qui.Aggiungerò, tuttavia, che sembra che tu voglia un po 'di controllo sul modo in cui vengono effettuati i confronti; se 'COM8' si riferisce a un identificatore di porta seriale, allora che ci si vuole eseguire un case-insensitive confronto:

var result = com2.Except(com1, StringComparer.OrdinalIgnoreCase); 
Problemi correlati