2013-05-17 25 views
8

Cách sử dụng LINQ để xóa một số yếu tố khỏi IList dựa trên một IList khác. Tôi cần xóa hồ sơ khỏi danh sách1 trong đó ID có trong danh sách2. Dưới đây là mẫu mã,LINQ để loại bỏ các yếu tố nhất định khỏi IList <T> dựa trên IList <int>

class DTO 
{ 

    Prop int ID, 
    Prop string Name 
} 

IList<DTO> list1; 

IList<int> list2; 



foreach(var i in list2) 
{ 
    var matchingRecord = list1.Where(x.ID == i).First(); 
    list1.Remove(matchingRecord); 
} 

Đây là cách tôi làm, có cách nào tốt hơn để làm tương tự.

+6

Không có ngày nào không có câu hỏi tương tự. –

+0

Không sử dụng LINQ cho việc này. Linq là tất cả về lọc và tạo chuỗi mới, chứ không phải sửa đổi bộ sưu tập. –

Trả lời

8

Bạn có thể sử dụng Where cho đơn giản hơn:

list1 = list1.Where(x => !list2.Contains(x.ID)) 
      .ToList(); 

Nhưng bạn thực sự cần phải loại bỏ tại chỗ, thích @ câu trả lời DanielHilgarth của

+3

RemoveAll không trả về một danh sách, nó trả về một int đại diện cho số lượng các mục bị xóa. –

+0

@RobertJ .: Đã chỉnh sửa câu trả lời của tôi –

+0

@RobertJ. bạn nên sử dụng RemoveAll, xem câu trả lời của tôi –

12

Tôi sẽ sử dụng phương pháp này:

var itemsToRemove = list1.Where(x => list2.Contains(x.ID)).ToList(); 
foreach(var itemToRemove in itemsToRemove) 
    list1.Remove(itemToRemove); 

Cách tiếp cận này loại bỏ các mục tại chỗ. Nó được sử dụng tốt nhất cho các trường hợp có nhiều mục trong số list1 và ít trong list2.
Nếu số lượng các mục trong list1list2 là tương tự, cách tiếp cận từ Cường Lê là một lựa chọn tốt.

+1

Tại sao một 'ToList()' sau 'Where'? Đừng nghĩ điều đó là cần thiết. –

+2

@GeorgeDuckett: Vâng, nó là cần thiết. Nếu không 'itemsToRemove' sẽ lặp lại trên' list1'. Cùng với 'Remove', điều này sẽ mang lại một bộ sưu tập' InvalidOperationException': * đã được sửa đổi; hoạt động điều tra có thể không thực hiện * –

+0

Ahh, tốt, quên mất điều đó. –

11

Bạn có thể viết phương thức mở rộng "RemoveAll()" cho IList<T> hoạt động chính xác như List.RemoveAll(). (Đây là nói chung đủ hữu ích để giữ trong thư viện lớp thông thường.)

Ví dụ (kiểm tra lỗi xóa do rõ ràng, bạn sẽ cần phải kiểm tra các thông số không phải là null):

public static class IListExt 
{ 
    public static int RemoveAll<T>(this IList<T> list, Predicate<T> match) 
    { 
     int count = 0; 

     for (int i = list.Count - 1; i >= 0; i--) 
     { 
      if (match(list[i])) 
      { 
       ++count; 
       list.RemoveAt(i); 
      } 
     } 

     return count; 
    }   

Sau đó, để xóa các mục khỏi danh sách1 theo yêu cầu thực sự sẽ trở nên đơn giản như:

list1.RemoveAll(item => list2.Contains(item.ID)); 
Các vấn đề liên quan