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

vxf3dgd4  于 2022-12-15  发布在  其他
关注(0)|答案(3)|浏览(128)

在linq里有没有什么操作是沿着......

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

我只找到了RemoveAll,它只返回一个数字(这不是很有帮助)和Except,它只接受另一个列表。
编辑:所以我被要求一个更好的用例(可以理解)。我的用例基本上是:我有一个对象列表,这些对象应该根据某些属性进行分组。这些组不重叠,所以一旦一个元素是一个组的一部分,它就不能是任何其他组的一部分。这也意味着,做一些事情,如

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

是对时间的巨大浪费(因为它一次又一次地遍历相同的项,即使它们已经没有任何用处了。因此,从列表中删除过滤掉的元素是有意义的。)
现在考虑一下,我将尝试使用ToLookup或GroupBy,即使这意味着分组条件将非常糟糕。

gupuwyp2

gupuwyp21#

从列表中获取已移除的元素。
你必须反转你的过滤器并得到元素。你不能在使用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附加到它上面。

lsmepo6l

lsmepo6l2#

我从未见过这样的东西,但你可以用几行代码做到这一点:

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))
如果您希望它更短,可以创建自己的扩展方法。

pod7payv

pod7payv3#

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

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

相关问题