同时采取和删除的Linq方法?

时间:2014-02-25 20:37:11

标签: c# linq

是否有同时TakeRemove的linq方法。

假设我想将前五个元素从一个列表移动到另一个列表。我确信我可以用几个linq语句来做到这一点,但有时我发现我已经重新发明了一个已经存在的方法。

现在有这样的方法吗? (如果不是我可以做到。)

5 个答案:

答案 0 :(得分: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));

答案 1 :(得分: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);

答案 2 :(得分:1)

不,没有。你应该创建自己的。我不确定在同一个动作中读取和修改列表是否是一个好主意。

答案 3 :(得分: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]);

答案 4 :(得分: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