2014-11-28 13 views
7

Tôi có danh sách chứa một số đối tượng và muốn sử dụng LINQ để xóa một mục cụ thể nhưng không chắc chắn cách thực hiện.Xóa một mục cụ thể khỏi danh sách bằng LINQ

foreach (var someobject in objectList) 
{ 
    if (someobject.Number == 1) // There will only one item where Number == 1. 
    { 
     list.remove(someobject) 
    } 
} 
+2

Vì vậy, mã của bạn không hoạt động hoặc cái gì? –

+0

Trái ngược với những gì bạn đang khiếu nại, mã hiện tại của bạn không liên quan đến LINQ. Bạn có lý do cụ thể cho việc muốn/cần một giải pháp dựa trên LINQ? Hoặc bất kỳ giải pháp hiệu quả nào khác cũng có thể chấp nhận được không? – stakx

+1

@VsevolodGoloviznin: Đoạn mã trên không thể hoạt động vì nó có chứa các lỗi cú pháp - 'list.remove (someobject)'. – stakx

Trả lời

27

Bạn cannot use a foreach to remove items trong liệt kê, bạn sẽ nhận được một ngoại lệ khi chạy.

Bạn có thể sử dụng List.RemoveAll:

list.RemoveAll(x => x.Number == 1); 

hoặc, nếu nó thực sự không phải là một List<T> nhưng bất kỳ chuỗi, LINQ:

list = list.Where(x => x.Number != 1).ToList(); 

Nếu bạn chắc chắn rằng chỉ có một mục với con số đó hoặc bạn muốn xóa một mục ở mức tối đa, bạn có thể sử dụng cách tiếp cận vòng lặp được đề xuất trong câu trả lời khác hoặc điều này:

var item = list.FirstOrDefault(x => x.Number == 1); 
if(item ! = null) list.Remove(item); 

Liên kết đến câu hỏi khác mà tôi đã đăng gợi ý rằng bạn có thể sửa đổi bộ sưu tập trong quá trình liệt kê trong C# 4 và sau đó. Không, bạn không thể. That applies only to the new concurrent collections.

+2

Trong trường hợp này bạn thực sự có thể sử dụng foreach vì chỉ có một mục cần xóa. Chỉ cần đảm bảo sử dụng ngắt để thoát khỏi vòng lặp sau khi mục đã bị xóa, nếu không bạn sẽ nhận được một ngoại lệ về lần lặp tiếp theo. Điều đó nói rằng, tôi nghĩ rằng giải pháp với RemoveAll() là thanh lịch hơn. – haagel

2

Bạn không thể sử dụng foreach để xóa mục khỏi bộ sưu tập. Điều này sẽ ném một ngoại lệ mà bộ sưu tập được sửa đổi.

Bạn có thể thực hiện nó với cho

for (int i=objectList.Count-1; i>=0 ; i--) 
{ 
    if (objectList[i].Number == 1) // there will only one item with Number = 1 
    { 
     objectList.Remove(objectList[i]); 
    } 
} 

trường hợp khác là sử dụng Remove/RemoveAll như Tim Schmelter chương trình.

+0

Như đã chỉ ra ở nơi khác, nếu bạn đang hạnh phúc để 'break' sau khi bạn tìm thấy một trận đấu, không có lý do gì để chuyển vòng lặp' foreach' thành một vòng lặp 'for'. – Rawling

+1

@Rawling một số người khác đã thêm tuyên bố ngắt. Dù sao, câu trả lời ngay từ đầu cũng không tốt. – mybirthname

-1

bạn có thể loại bỏ ở các chỉ số nếu giá trị đáp ứng các tiêu chí

for (int i=0; i < objectList.Count; i ++) 
{ 
    if (objectList[i].Number == 1) // there will only one item with Number = 1 
    { 
     objectList.RemoveAt[i]; 
    } 
} 
1

Bạn có thể dùng một vòng lặp foreach để loại bỏ một mục từ danh sách. Điều quan trọng là sử dụng ngắt để dừng vòng lặp khi bạn đã xóa mục. Nếu vòng lặp tiếp tục sau khi một mục bị xóa khỏi danh sách, một ngoại lệ sẽ được ném ra.

foreach (var someobject in objectList) 
{ 
    if (someobject.Number == 1) // There will only one item where Number == 1 
    { 
     objectList.remove(someobject); 
     break; 
    } 
} 

Tuy nhiên, điều này chỉ sẽ làm việc nếu chỉ có một đối tượng bạn muốn loại bỏ, như trong trường hợp của bạn.

Các vấn đề liên quan