2014-02-25 39 views
1

是否有linq方法,將TakeRemove在同一時間。Linq同時取走的方法?

假設我想將前五個元素從一個列表移到另一個列表。我確信我可以用幾個linq語句來做到這一點,但有時我發現我已經重新發明了一個已經存在的方法。

現在有這樣的方法嗎? (如果沒有,我很好。)

+1

我覺得你奇怪,你實際上*希望*變異與linq語句的集合。 – asawyer

+1

根本沒有Linq語句(方法)。刪除是對List <>的操作,而不是對IEnumerable <>的操作。 –

+0

你不會想。這將等同於在枚舉集合的同時修改集合,並導致運行時異常。 –

回答

1

不,沒有。你應該創建你自己的。我不確定在相同的行動中閱讀和修改列表是否會是一個好主意。

4

不,沒有。 LINQ代表語言集成查詢,其所有方法都用於導航和檢查現有集合。它沒有任何方法來改變集合。

但是,您可以使用某些List<T>類的方法。儘管如此,還沒有單一的方法。這裏有一個最小的解決方案:

list1.AddRange(list2.Take(5)); 
list2.RemoveRange(0, 5); 

但如果你真的願意,你可以在自定義的擴展方法把這個包:

public static class MyListExtensions { 
    public static IEnumerable<T> TakeAndRemove<T>(this List<T> list, int count) { 
     foreach(var n in list.Take(count)) 
      yield return n; 
     source.RemoveRange(0, count); 
    } 
} 

list1.AddRange(list2.TakeAndRemove(5)); 
2

是沒有LINQ的方法做一個單獨的語句。我有最小的解決方案是這樣的

List<string> one = new List<string>() { "1", "2", "3", "4", "5", "6", "7" }; 
List<string> two = new List<string>() { "1", "2", "3", "4", "5", "6", "7" }; 

two.AddRange(one.Take(5)); 
one.RemoveRange(0, 5); 
1

LINQ不能有這樣的方法,因爲它不會改變傳遞給它的集合。但是,您可以使用LINQ爲您完成大部分工作。

考慮一個例子:假設您需要從listA中刪除所有通過特定條件的項目,並將它們添加到listB。您可以將LINQ分區listA放入您希望保留的部分以及您希望刪除的部分,然後將所有刪除的項目添加到listB。這裏是你如何能做到這:

// Let's say you want to remove all items with name starting in "X" 
// The dictionary will contain two keys - true and false 
// Items to keep will be under "true"; items to remove will be under "false" 
var d = listA 
    .GroupBy(item => !item.Name.StartsWith("X")) 
    .ToDictionary(p => p.Key, p => p.ToList()); 
// Reassign the list of items that you keep to listA 
listA = d[true]; 
// Add items from the list of items to be removed to listB 
listB.AddRange(d[false]); 
+0

而不是'GroupBy'後跟'ToDictionary',你可以使用'ToLookup'。它更快,更輕鬆,而且四處都更好。 – Servy

1

沒有現有的LINQ方法,做這一點,但好像你可以在說List<T>之上構建一個。基本結構是有一個謂詞去除這些值,函數返回被刪除的一組值。

static List<T> RemoveAndReturn<T>(this List<T> list, Predicate<T> predicate) { 
    var removed = new List<T>(); 
    int i = 0; 
    while (i < list.Count) { 
    var current = list[i]; 
    if (predicate(current)) { 
     removed.Add(current); 
     list.RemoveAt(i); 
    } else { 
     i++; 
    } 
    } 

    return removed; 
} 

請注意,這不是真正符合LINQ的精神,但因爲第一部分執行迅速,而不是延遲時間。這是必要的,恕我直言,以避免意外雙刪除

用這種方法,你可以做類似LINQ的查詢,刪除和操作。但它會更好地稱他們流利,而不是LINQ