2009-07-26 68 views
27

現在我來了一個階段,將所有數據作爲緩存(對象)中的一個列表,我接下來要做的就是從列表中刪除一些實例。使用LINQ或Lambda從列表中刪除實例?

通常情況下,我會做消除這樣的:

List<T> list; 
List<T2> toBeRemovedItems; 
// populate two lists 
foreach(T2 item in toBeRemovedItems) 
{ 
    list.Remove(delegate(T one) { 
     // build a condition based on item 
     // return true or false 
    }); 
} 

更具體地講,其實我建立或填充動態類(不是一個正式的定義的類)的toBeRemvoedItems名單。例如,T艙是像MyClass的和代碼去除是:

class MyClass<C> { 
    public string Value1 { get; set; } 
    public int Value2 { get; set; } 
    public C ObjectC { get; set; } 
} 
.... 
List<MyClass<C>> list; 
// populate list 
// populate toBeRemovedItems. Here is an example of hard-coded codes: 
var toBeRemovedLItems = new[] { 
    new { Value1="a", Value2 = 1}, 
    new { Value2="x", Value2 = 10}, 
    ... 
}; 
// toBeRemovedItems may be the result of Select from a collection 
foreach(var item in toBeRemovedLItems) 
{ 
    list.Remove(delegate(MyClass one) { 
     return one.Value1 = item.Value1 && one.Value2 < item.Value2; 
    }); 
} 

我試圖從MSDN IEnumerable界面搜索Remove()方法,但我找不到Remove()有方法(它是有道理的IEnumerable僅用於枚舉)。在List類中,有幾個超載的方法。我不確定是否有其他方法通過使用LINQ或Lambda表達式從列表中刪除項目?

順便說一句,我想過一種方法來對列表進行查詢,以獲取Where條件的子集或新的IEnumerable列表,類似於從列表中移動項目。但是,我更喜歡從我的緩存列表中刪除項目,並且在某些情況下,我無法將類中的列表屬性重置爲新列表(例如專用集)。

+0

看起來像一個笨蛋。那麼,基本上你提到了所有可能的方法在帖子本身... http://stackoverflow.com/questions/1120336/what-is-the-easiest-way-to-foreach-through-a-listt-removing-unwanted -objects – 2009-07-26 19:36:18

回答

40

你可以使用方法removeall過

MyClass one; //initialize MyClass 
list.RemoveAll(item => one.Value1 == item.Value1 && one.Value2 < item.Value2); 
+7

我認爲它實際上是表的方法,而不是擴展方法 – Jimmy 2009-07-26 19:29:30

+0

謝謝!我更新了我的帖子。 – 2009-07-26 19:30:43

+0

我瞭解你的代碼是你一次刪除一個項目。我仍然必須像Rchard Hein的建議一樣循環。 – 2009-07-26 20:07:09

2
foreach(var item in toBeRemovedLItems) { 
    list.RemoveAll(one => one.Value1 == item.Value1 && one.Value2 < item.Value2); 
} 

太又遲到了。好吧。

+0

不知道是否可以將兩個參數傳遞給RemoveAll(lambda func)以除去toBeRemovedItems,而不通過foreach循環。肯定它已經很可讀了。 – 2009-07-26 20:09:35

21

您可以使用LINQ的Where方法來過濾不應該成爲列表一部分的值。結果是一個IEnumerable<T>刪除了元素。

var res = list.Where(item => !(one.Value1 == item.Value1 && one.Value2 < item.Value2)); 

這不會更新原有List<T>實例,而是將創建一個新IEnumerable<T>與刪除的值。

+0

什麼是性能。打這樣做與一個for循環刪除項目? – 2015-08-23 21:29:38

4

我同意過濾掉某些項目的Jared的建議,但它看起來像Value1一個join將是一個更有效的方法:

var res = from item1 in list 
      join item2 in toBeRemovedList 
      on item1.Value1 equals item2.Value1 
      where item1.Value2 >= item2.Value2 
      select item1; 

更新:顯然,我不能在閱讀理解能力 - 新方法:

var removeDict = toBeRemovedList.ToDictionary(i => i.Value1, i => i.Value2); 
list.RemoveAll(item => { 
    int itemToRemoveValue2; 
    if(removeDict.TryGetValue(item.Value1, out itemToRemoveValue2)) 
     return item.Value2 < itemToRemoveValue2; 
    return false; 
}); 

當然,如果您的列表刪除可能以字典開頭,那將會更好。最終,我們只是想讓我們的配對Value1更有效率。

5

如果我正確地得到問題,從兩個列表中產生一個唯一的集合。

爲此,您可以使用以下內容

List list1; List list2;

List list3 = list1。除(列表2)

的項目list3將包含獨特的項目。

1

對於不屬於列表(不能暴露RemoveAll),你仍然可以刪除與一個班輪項目的集合。

要更換直列,只是生成項目的列表中刪除,然後通過運行它,並執行刪除代碼。

var dictionary = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}}; 
dictionary 
    .Where(where_item => 
     ((where_item.Key == "foo") && (where_item.Value == "0")) 
     || ((where_item.Key == "boo") && (where_item.Value == "1")) 
    ) 
    .ToList() 
    .ForEach(remove_item => { 
     dictionary.Remove(remove_item.Key); 
    }); 

要在副本中替換,只需生成一個過濾的枚舉並返回一個新的副本。

var dictionary0 = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}}; 
var dictionary1 = dictionary0 
    .Where(where_item => 
     ((where_item.Key == "foo") && (where_item.Value == "0")) 
     || ((where_item.Key == "boo") && (where_item.Value == "1")) 
    ) 
    .ToDictionary(each_item => each_item.Key, each_item => each_item.Value); 
0

也許你正在試圖做這樣的事情?

List<T> firstList; 
List<T2> toBeRemovedItems; 
List<T> finalList; 

foreach(T item in firstList) 
{ 
    toBeRemovedItems = CheckIfWeRemoveThisOne(item.Number, item.Id); 
    if (toBeRemovedItems == null && toBeRemovedItems.Count() == 0) 
     finalList.Add(item); 
} 

這是我如何設法解決的問題有List<ViewModel>List<Model>之間擺脫重複的。我使用CheckIfWeRemoveThisOne函數檢查item.Number是否屬於某個其他項目,並使用ID作爲定義特性。如果發現了另一個項目(一式兩份),而不是試圖從原來的列表中刪除(這讓我取回一個List<Model>和被賦予了List<ViewModel>到我擺在首位的功能,所以我有我的懷疑,我怎麼無論如何,我可以做到),我只是建立了一個新的列表 - 如果發現它是好的,那就把結果添加進去。

相關問題