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

本文关键字:操作 列表 删除 | 更新日期: 2023-09-27 18:22:12

linq中是否有任何操作符合。。。

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

我只找到了RemoveAll,它只是返回一个数字(这不是很有帮助),而Except只是获取另一个列表。

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

var group1 = list.Where(...)
var group2 = list.Where(...)
...

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

现在考虑一下,我将尝试使用ToLookup或GroupBy,即使这意味着分组条件将非常糟糕。

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

从列表中获取已删除的元素。

你必须反转你的过滤器并获得元素。使用List<T>.RemoveAll删除元素后,无法获得已删除的元素。你可以做很多事情:

  1. 反转过滤器

代码:

var toBeRemovedItems = myList.Where(r=> !(yourFilter)); //.ToList() to get a list back
  1. 另一种方法可以是保留列表的副本,然后从原始列表中删除,并使用Except来获得差异(应该避免,因为这会令人困惑和消耗内存)

List.RemoveAll确实返回从列表中删除的元素数,并且它还从列表中移除元素

你可以这样使用:

myList.RemoveAll([filter])

这将在适当的位置修改列表。

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

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

如果你想要一个新的列表,那么你可以把ToList附加到它上面。

我从来没有见过这样的东西,但你可以用几行代码来完成:

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

由于.ToList()removed将保留元素(否则,您仍将处理由于.RemoveAll()而修改的列表项)。另一种选择是仅具有Where(x => Filter(x))和相反的Where(x => !Filter(x))

如果你想让它更短,你可以制作自己的扩展方法。

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

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