2010-09-30 21 views

Odpowiedz

34

Jeśli Potrzebują tylko identyfikatory przedmiotów, a następnie Mark's answer ładnie załatwią sprawę. Jeśli trzeba powrócić samych przedmiotów (i nie mają już odpowiednią realizację Equals) to można spróbować czegoś takiego:

// assumes that the ID property is an int - change the generic type if it's not 
var ids = new HashSet<int>(list1.Select(x => x.ID)); 
var results = list2.Where(x => !ids.Contains(x.ID)); 
+0

Dlaczego umieścić w HashSet? (Możliwe: var ids = list1.Select (x => x.ID);) –

+1

@ David_001: Można to zrobić, ale wtedy wyszukiwanie "Zawiera" byłoby O (n), a nie O (1), wykonanie zapytania jako całości O (n * m) zamiast O (n + m). Prawdą jest, że prawdopodobnie nie byłoby to zauważalne w przypadku mniejszych kolekcji, ale gdyby było wiele elementów, wydajność naprawdę ucierpiałaby bez wyszukiwania O (1) zapewnionego przez 'HashSet '. – LukeH

+0

Tak, nie brałem pod uwagę wydajności. HashSet będzie znacznie szybszy w prawie wszystkich sytuacjach, ale szczególnie w przypadku dużych rozmiarów list2. Z tego powodu jest to najlepsze rozwiązanie tego problemu, ale myślę, że mogłeś przeoczyć koszt konstruktora dla HashSet w swoich wielkich sumach O. W szczególności, jeśli lista2 będzie bardzo mała (powiedzmy 10 pozycji), Contains nie jest jedynym wąskim gardłem, tworzenie listy ids jest, a poniższe będą szybsze (bez względu na rozmiar listy1): "var ids = lista1.Wybierz (x => x.ID) .ToList(); " –

22

To będzie Ci identyfikatory, które są tylko w listy2:

var ids = list2.Select(x => x.Id).Except(list1.Select(x => x.Id)); 

Jeśli obiekty porównać równe, gdy mają ten sam identyfikator następnie można uprościć do:

var objects = list2.Except(list1); 
Powiązane problemy