从列表中删除匹配项的操作
本文关键字:操作 列表 删除 | 更新日期: 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
删除元素后,无法获得已删除的元素。你可以做很多事情:
- 反转过滤器
代码:
var toBeRemovedItems = myList.Where(r=> !(yourFilter)); //.ToList() to get a list back
- 另一种方法可以是保留列表的副本,然后从原始列表中删除,并使用
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])