2010-11-01 43 views
25

Tôi đang học viết lambda expressions và tôi cần trợ giúp về cách xóa tất cả các phần tử khỏi danh sách không có trong danh sách khác.Xóa các mục khỏi danh sách 1 không có trong danh sách 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); 
} 

Trả lời

49

Bạn có thể làm điều này thông qua RemoveAll sử dụng Chứa:

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

Ngoài ra, nếu bạn chỉ muốn ngã tư, sử dụng Enumerable.Intersect sẽ hiệu quả hơn:

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

Sự khác biệt là, trong trường hợp sau, bạn sẽ không nhận được các mục trùng lặp. Ví dụ: nếu list2 chứa 2, trong trường hợp đầu tiên, bạn sẽ nhận được {2,2,4,5}, trong lần thứ hai, bạn sẽ nhận được {2,4,5}.

+0

xem phần nâng cao của tôi cho câu trả lời này (dưới đây) nếu bạn so sánh các đối tượng hơn là vô hướng – horace

8

Câu hỏi này đã được đánh dấu là đã trả lời, nhưng có sự bắt kịp. Nếu danh sách của bạn có chứa một đối tượng, chứ không phải là một vô hướng, bạn cần phải làm việc nhiều hơn một chút.

Tôi đã cố gắng này hơn và hơn với Remove() và RemoveAt() và tất cả các loại sự vật và không ai trong số họ làm việc một cách chính xác. Tôi thậm chí không thể có được một Contains() để hoạt động chính xác. Không bao giờ khớp với bất kỳ thứ gì. Tôi đã bối rối cho đến khi tôi nhận được sự nghi ngờ rằng có lẽ nó không thể phù hợp với mục một cách chính xác.

Khi tôi nhận ra điều này, tôi đã tái cấu trúc lớp mục để triển khai IEquatable và sau đó nó bắt đầu hoạt động.

Đây là giải pháp của tôi:

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

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

     return false; 
    } 
} 

Sau khi tôi đã làm điều này, các RemoveAll trên() câu trả lời bởi Reed Copsey làm việc một cách hoàn hảo đối với tôi.

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

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

giải pháp dễ dàng hơn cho các đối tượng hơn Horace đã:

Nếu danh sách của bạn có chứa một đối tượng, chứ không phải là một đại lượng vô hướng, nó là đơn giản, bằng cách loại bỏ bởi một thuộc tính được chọn của các đối tượng:

var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId)); 
Các vấn đề liên quan