从列表中删除匹配项的操作?

时间:2015-11-17 15:36:10

标签: c# linq

linq中的任何操作是否都符合......

IEnumerable<...> removed = myList.RemoveWhere([filter])

我只发现RemoveAll只返回一个数字(这不是很有帮助)而Except只返回另一个列表。

编辑:所以我被要求提供更好的用例(可以理解)。我的用例基本上是:我有一个对象列表,应该根据某些属性进行分组。这些组不重叠,因此一旦元素成为组的一部分,它就不能成为任何其他元素的一部分。这也意味着,做像

这样的事情
var group1 = list.Where(...)
var group2 = list.Where(...)
...

是一个巨大的浪费时间(因为它一次又一次地经历相同的项目,即使它们已经不再使用了。因此从列表中删除过滤掉的元素是有意义的。

现在考虑一下,我会尝试使用ToLookup或GroupBy,即使这意味着分组条件会像地狱一样丑陋。

3 个答案:

答案 0 :(得分:2)

  

从列表中删除元素。

您必须反转过滤器并获取元素。使用List<T>.RemoveAll删除元素后,无法删除元素。您可以做多件事:

  1. 反转过滤器。
  2. 代码:

    var toBeRemovedItems = myList.Where(r=> !(yourFilter)); //.ToList() to get a list back
    
    1. 另一种方法可能是保留列表的副本,然后从原始列表中删除并使用Except来获取差异(应该避免,因为它会让人感到困惑和消耗内存)< / em>的。
    2. List.RemoveAll会返回从列表中删除的元素数量,也会从列表中删除元素。

      你可以使用它:

      myList.RemoveAll([filter])
      

      这将修改列表。

      但这仅适用于List<T>,如果您想使用IEnumerable<T>,则可以使用Where过滤掉值,然后将结果分配回来:

      var result  = yourList.Where(r=> r != yourCondition);
      

      如果您想要新的列表,则可以向其添加ToList

答案 1 :(得分:1)

我没有看到过这样的内容,但你可以用几行代码完成:

var removed = list.Where(x => Filter(x)).ToList();
list.RemoveAll(x => removed.Contains(x));
由于removed

.ToList()会保留元素(否则,您仍然会处理列表项,因为.RemoveAll()而修改了列表项)。另一种选择就是拥有Where(x => Filter(x))和相反的Where(x => !Filter(x))

如果您想缩短它,可以制作自己的扩展方法。

答案 2 :(得分:0)

尝试使用Where子句对条件进行逻辑否定,只返回其值不代表条件的元素:

IEnumberable<...> removed = myList.Where( x => ![filter])