2012-06-12 15 views
21

Jak porównać dwa ciągi tablicowe przy użyciu C# .net? NpJak uzyskać różnice między dwoma tablicami ciągów w języku C#?

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

Tutaj COM1 i COM2 są Array ciąg. Wynik: COM8. Jak to osiągnąć?

+9

Byłoby naprawdę pomóc jeśli chcesz podać więcej szczegółów na temat porównania, które chcesz zrobić. Na przykład, czy uważasz porządek za ważny? Walizka? A co jeśli element występuje w 'com1', ale nie' com2'? –

Odpowiedz

6

myślę, że to najkrótsza droga do rozwiązania tego

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

Używanie LINQ Except extension:

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

Sugestia: zmień 'wynik' na' z wyjątkiem' (lub na odwrót) – Default

49

Brzmi jak chcesz wszystko w array2wyjątkiem co w array1:

var onlyInArray2 = array2.Except(array1); 

Oczywiście, jeśli również chciał wiedzieć, co było tylko w array1 można użyć:

var onlyInArray1 = array1.Except(array2); 

(To wszystko wymaga .NET 3.5 lub wyższej lub alternatywnej implementacji LINQ to Objects, takiej jak LINQBridge.)

Zakładam, że kolejność nie jest ważna przy obliczaniu różnic - Except jest operatorem opartym na zestawie, więc zakłada, że ​​traktuje się kolekcje jako zestawy.

Zauważ, że Except prostu zwraca IEnumerable<T> - jeśli chcesz wyniki jako tablic, trzeba zadzwonić ToArray:

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

Jeśli chcesz różnica symetryczna, tzn tylko dbają o których wartości są w jednej tablicy, zamiast którego tablica z którego pochodzą, można użyć:

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

lub można użyć HashSet bezpośrednio:

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

We wszystkich tych przypadkach wynikowa kolejność jest niezdefiniowana, chociaż w praktyce Except zachowa pierwotną kolejność pierwszego argumentu. Chociaż jest to ściśle rzecz biorąc szczegół wdrożenia, myślę, że jest mało prawdopodobne, aby się to zmieniło.

Podobnie jak inne podmioty gospodarcze określone oparte na LINQ, Except powróci tylko raz dowolnego elementu - więc jeśli COM8 pojawił się dwa razy w array2, wydaje się tylko raz w wyniku.

+1

Jego Królewska Mość Jon, dodaje jeszcze coś więcej ;-) – aleroot

+2

Myślę, że z twoimi lepszymi odpowiedziami tutaj mógłbyś napisać kolejną książkę ... kupię to na pewno! – aleroot

2

Jeśli chcesz wszystko, co znajduje się w jednej liście, ale nie oba, w jednym wyrażeniu, można użyć Union, IntersectiExcept:

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

+, ten jest inteligentny! –

1

Jak inni już wspomniano, metoda rozszerzenie Except jest zdecydowanie droga tutaj.Dodam jednak, że wygląda na to, że potrzebna jest pewna kontrola nad sposobem dokonywania porównań; jeśli „COM8” odnosi się do portu szeregowego identyfikatora, a następnie, że chcesz wykonać bez uwzględniania wielkości liter porównania:

var result = com2.Except(com1, StringComparer.OrdinalIgnoreCase); 
Powiązane problemy