2010-11-01 27 views
25

Uczę się pisać lambda expressions i potrzebuję pomocy, jak usunąć wszystkie elementy z listy, które nie znajdują się na innej liście.Usuń pozycje z listy 1 nie ma na liście 2

var list = new List<int> {1, 2, 2, 4, 5}; 
var list2 = new List<int> { 4, 5 }; 

// Remove all list items not in List2 
// new List Should contain {4,5}  
// The lambda expression is the Predicate. 
list.RemoveAll(item => item. /*solution expression here*/); 

// Display results. 
foreach (int i in list) 
{ 
    Console.WriteLine(i); 
} 

Odpowiedz

49

Można to zrobić poprzez removeAll użyciu Zawiera:

list.RemoveAll(item => !list2.Contains(item)); 

Alternatywnie, jeśli chcesz tylko do skrzyżowania, przy użyciu Enumerable.Intersect byłoby bardziej efektywne:

list = list.Intersect(list2).ToList(); 

Różnica polega na tym, w tym drugim przypadku nie otrzymasz duplikatów. Na przykład, jeśli list2 zawierał 2, w pierwszym przypadku dostaniesz {2,2,4,5}, w drugim dostaniesz {2,4,5}.

+0

zobacz moje rozszerzenie do tej odpowiedzi (poniżej), jeśli porównujesz obiekty zamiast skalarów – horace

8

To pytanie zostało oznaczone jako odpowiedź, ale wystąpił błąd. Jeśli twoja lista zawiera obiekt, a nie skalar, musisz wykonać nieco więcej pracy.

Próbowałem tego w kółko za pomocą Remove() i RemoveAt() i wszelkiego rodzaju rzeczy i żaden z nich nie działał poprawnie. Nie mogłem nawet uruchomić funkcji Contains(). Nigdy niczego nie pasowałem. Byłem zaskoczony, dopóki nie zacząłem podejrzewać, że może nie mógł poprawnie dopasować przedmiotu.

Kiedy zdałem sobie z tego sprawę, odnowiłem element item w celu zaimplementowania IEquatable, a następnie zaczęło działać.

Oto moje rozwiązanie:

class GenericLookupE : IEquatable<GenericLookupE> 
{ 
    public string ID { get; set; } 

    public bool  Equals(GenericLookupE other) 
    { 
     if (this.ID == other.ID)  return true; 

     return false; 
    } 
} 

Po Zrobiłem to, powyższy removeAll() Odpowiedź przez Reed Copsey działało idealnie dla mnie.

Patrz: http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

8
list = list.Except(list2).ToList(); 
2

prostsze rozwiązanie dla obiektów niż Horacego dał:

Jeśli lista zawiera obiekt, zamiast skalar, to takie proste, usuwając przez jednej wybranej nieruchomości obiektów:

var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId)); 
Powiązane problemy