Co jest najszybsze (i najmniej wymagające zasobów) do porównania dwóch masywnych (> 50 000 pozycji), w wyniku czego mają dwie listy takie jak te poniżej:
- elementy, które pojawiają się na pierwszej liście, ale nie na drugiej
- elementy, które pojawiają się na drugiej liście, ale nie na pierwszej
Obecnie pracuję z List lub IReadOnlyCollection i rozwiązuję ten problem w zapytaniu linq:
var list1 = list.Where(i => !list2.Contains(i)).ToList();
var list2 = list2.Where(i => !list.Contains(i)).ToList();
Ale to nie działa tak dobrze, jak bym chciał. Masz pomysł, aby uczynić to szybszym i mniej wymagającym zasobów, ponieważ muszę przetworzyć wiele list?
Equals(object)
i / lub zaimplementujeIEquatable<T>
, powinno być w porządku.IEquatable<T>
implementacji lubobject.Equals(object)
metody. Wygląda na to, że powinieneś utworzyć nowe pytanie z minimalnym, powtarzalnym przykładem - nie możemy tak naprawdę zdiagnozować rzeczy w komentarzach.Bardziej wydajne byłoby użycie
Enumerable.Except
:Ta metoda jest implementowana przy użyciu odroczonego wykonania. Oznacza to, że możesz napisać na przykład:
Jest również wydajny, ponieważ wewnętrznie używa a
Set<T>
do porównywania obiektów. Działa najpierw poprzez zebranie wszystkich różnych wartości z drugiej sekwencji, a następnie przesłanie strumieniowe wyników pierwszej, sprawdzając, czy nie były wcześniej widoczne.źródło
Set<T>
jest budowana z drugiej sekwencji (tzn. Jest w pełni iterowana i przechowywana), a następnie dostarczane są elementy, które można dodać z pierwszej sekwencji.Where
jest częściowo odroczone, ponieważ wlist.Where(x => x.Id == 5)
wartości liczby5
jest przechowywany na początku, a nie leniwie.Działa to dla wszystkich pierwotnych typów danych. Jeśli chcesz użyć go na niestandardowych obiektach, musisz je zaimplementować
IEqualityComparer
Definiuje metody wspomagające porównywanie obiektów pod kątem równości.
źródło
SequenceEqual
jest prostybool
. OP chce dwóch list wyników - i opisuje, czego chcą w zakresie ustawianych operacji: „elementy, które pojawiają się na pierwszej liście, ale nie na drugiej”. Nie ma żadnych oznak, że kolejność jest istotna, natomiast SequenceEqual nie uznają to za stosowne. To wydaje się odpowiadać na zupełnie inne pytanie.Jeśli chcesz, aby wyniki nie uwzględniały wielkości liter , następujące funkcje będą działać:
firstNotSecond
zawierałby b1.dllsecondNotFirst
zawierałby b2.dllźródło
Nie dla tego problemu, ale oto kod do porównania list na równe i nie! identyczne przedmioty:
źródło
Except
spróbuj w ten sposób:
źródło
Czasami musisz tylko wiedzieć, czy dwie listy są różne, a nie jakie są te różnice. W takim przypadku rozważ dodanie tej metody rozszerzenia do swojego projektu. Zauważ, że wymienione obiekty powinny implementować IEquatable!
Stosowanie:
Niezależnie od
Component
klasy, przedstawione tutaj metodyCar
powinny być implementowane prawie identycznie.Bardzo ważne jest, aby zauważyć, jak napisaliśmy GetHashCode. W celu prawidłowego wdrożenia
IEquatable
,Equals
iGetHashCode
moszczu działać na właściwości instancji w logicznie zgodny sposób.Dwie listy o tej samej zawartości są wciąż różnymi obiektami i będą generować różne kody skrótu. Ponieważ chcemy, aby te dwie listy były traktowane jako równe, musimy pozwolić na
GetHashCode
wygenerowanie tej samej wartości dla każdej z nich. Możemy to osiągnąć, delegując kod skrótu do każdego elementu na liście i używając standardowego bitowego XOR, aby połączyć je wszystkie. XOR jest niezależny od kolejności, więc nie ma znaczenia, czy listy są sortowane inaczej. Liczy się tylko to, że zawierają tylko równoważnych członków.Uwaga: dziwna nazwa ma sugerować fakt, że metoda nie uwzględnia kolejności elementów na liście. Jeśli zależy Ci na kolejności elementów na liście, ta metoda nie jest dla Ciebie!
źródło
Użyłem tego kodu do porównania dwóch list, które mają milion rekordów.
Ta metoda nie zajmie dużo czasu
źródło
Jeśli potrzebny będzie tylko łączony wynik, to również zadziała:
gdzie T jest rodzajem elementu listy.
źródło
Może to jest śmieszne, ale działa dla mnie
string.Join ("", List1)! = string.Join ("", List2)
źródło
Myślę, że jest to prosty i łatwy sposób na porównanie dwóch list element po elemencie
źródło
To najlepsze rozwiązanie, jakie znajdziesz
źródło
List<T>
dla każdego elementu wlist1
. Również wynik jest wywoływany,list3
gdy nie jest toList<T>
.