2012-04-16 62 views
7

這是從列表中刪除符合某些條件的項目,然後獲取這些項目的最簡單方法。LINQ:RemoveAll並獲取元素

我能想到的幾種方法,我不知道這是最好的一個:

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => x.Condition); 

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => subList.Contains(x)); 

是任何這一個最好的方法嗎?如果是,哪一個?如果不是,我該怎麼做?

回答

4

我會去爲了提高可讀性第一選擇,與你首先應該兌現清單,否則你會失去你想在下一行選擇非常項目注:

var sublist = list.Where(x => x.Condition).ToArray(); 
list.RemoveAll(x => x.Condition); 

第二個例子是沒有理由的O(n^2),最後一個很好,但可讀性較差。

編輯:現在我重讀了你的最後一個例子,請注意,因爲它現在寫入將會取出所有其他項目。您缺少條件檢查,刪除行實際上應該是list.RemoveAt(i--);,因爲i+1 th元素在刪除後成爲i th元素,並且當您增加i時,您正在跳過它。

+0

它實際上是爲O(n^3),但我假設缺乏物化的下滑只是你的心;) – Blindy 2012-04-16 17:10:16

+0

這些項目(如我寫的那樣)是否會通過第二條指令從subList中刪除? :O – Diego 2012-04-16 17:11:49

+0

呃你永遠不會從'子列表'中刪除,如果我正確地閱讀它,你也不打算這樣做。 – Blindy 2012-04-16 17:13:56

2

我喜歡使用函數式編程方法(只做新事物,不要修改現有的東西)。 ToLookup的一個優點是您可以處理多個項目的雙向拆分。

ILookup<bool, Customer> lookup = list.ToLookup(x => x.Condition); 
List<Customer> sublist = lookup[true].ToList(); 
list = lookup[false].ToList(); 

或者,如果你需要修改原始實例...

list.Clear(); 
list.AddRange(lookup[false]); 
+0

我認爲它非常複雜(幾乎沒有知識,我認爲它不是真正的表現)。這有什麼優勢嗎? – Diego 2012-04-16 18:36:26

+0

條件每個項目只能評估一次。列表實例未被修改,如果該列表實例在線程之間共享,這可能是一個很大的優勢。 – 2012-04-16 18:47:55