2012-06-12 5 views
21

Wie werden zwei Array-Strings mit C# .net verglichen? ZB:Wie bekomme ich die Unterschiede zwischen zwei String-Arrays in C#?

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

Hier com1 und com2 sind Array-String. Ergebnis: COM8. Wie erreicht man das?

+9

Es wäre wirklich zu lösen helfen wenn Sie genauere Angaben zu dem Vergleich machen würden, den Sie machen möchten. Zum Beispiel, halten Sie die Reihenfolge für wichtig? Fall? Was ist, wenn ein Element in "com1" aber nicht "com2" vorkommt? –

Antwort

6

ich denke, das ist der kürzeste Weg diese

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

Mit dem Linq Except extension:

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

Vorschlag: ändere 'result' in' except' (oder umgekehrt) – Default

49

Klingt wie Sie wollen alles in array2außer was in array1 ist:

var onlyInArray2 = array2.Except(array1); 

Natürlich, wenn Sie auch wissen wollte, was nur in array1 war Sie nutzen könnten:

var onlyInArray1 = array1.Except(array2); 

(Dies alles erfordert .NET 3.5 oder höher oder eine alternative LINQ to Objects-Implementierung wie LINQBridge.)

Ich nehme an, dass die Reihenfolge nicht wichtig ist, wenn Sie Unterschiede berechnen - Except ist ein Set-basierter Operator, also wird davon ausgegangen, dass Sie die Sammlungen als Sets betrachten.

Beachten Sie, dass Except gibt nur ein IEnumerable<T> - wenn Sie die Ergebnisse als Arrays wollen, müssen Sie ToArray nennen:

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

Wenn Sie die symmetrische Differenz wollen, dh Sie nur darüber, welche Werte kümmern sind in einem einzigen Array, anstatt dem Array sie kamen, könnten Sie verwenden:

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

oder könnten Sie HashSet direkt verwenden:

var set = new HashSet<string>(array1); 
// This modifies the set... 
set.SymmetricExceptWith(array2); 

In all diesen Fällen ist die resultierende Reihenfolge nicht definiert, obwohl in der Praxis Except die ursprüngliche Reihenfolge des ersten Arguments beibehalten wird. Während dies streng genommen ein Implementierungsdetail ist, denke ich, dass es sehr unwahrscheinlich ist, dass es sich ändert.

Wie die anderen Set-basierten Operatoren in LINQ, Except wird nur jedes Element zurück, sobald - also, wenn COM8 in array2 zweimal erschienen, wäre es nur einmal im Ergebnis erscheinen.

+1

Seine Majestät Jon, fügt immer noch etwas hinzu ;-) – aleroot

+2

Ich denke, dass du mit deinen besseren Antworten hier noch ein Buch schreiben könntest ... Ich werde kaufen es ist sicher! – aleroot

2

Wenn Sie alles wollen, die in einer Liste ist aber nicht beide, in einem einzigen Ausdruck, könnten Sie Union, IntersectundExcept:

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

+, das ist schlau! –

1

Wie andere schon gesagt haben, die Except Erweiterungsmethode ist auf jeden Fall den Weg hierher zu gehen.Ich füge jedoch hinzu, dass es so aussieht, als wollten Sie vielleicht eine Kontrolle darüber, wie die Vergleiche gemacht werden; wenn ‚COM8‘ bezieht sich auf einen seriellen Port-Kennung, dann würde wollen, dass Sie Groß- und Kleinschreibung Vergleich auszuführen:

var result = com2.Except(com1, StringComparer.OrdinalIgnoreCase); 
Verwandte Themen