LINQ:RemoveAll并删除元素

Die*_*ego 10 c# linq removeall

哪个是从列表中删除与某些条件匹配的项目的最简单方法,然后获取这些项目.

我可以从几个方面思考,我不知道哪个是最好的:

var subList = list.Where(x => x.Condition);
list.RemoveAll(x => x.Condition);
Run Code Online (Sandbox Code Playgroud)

要么

var subList = list.Where(x => x.Condition);
list.RemoveAll(x => subList.Contains(x));
Run Code Online (Sandbox Code Playgroud)

这是最好的方法吗?如果是,哪一个?如果不是,我该怎么办?

Amy*_*y B 7

我喜欢使用函数式编程方法(仅创造新事物,不修改现有事物)。优点之一ToLookup是您可以处理多个项目,而不是双向进行。

ILookup<bool, Customer> lookup = list.ToLookup(x => x.Condition);
List<Customer> sublist = lookup[true].ToList();
list = lookup[false].ToList();
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要修改原始实例...

list.Clear();
list.AddRange(lookup[false]);
Run Code Online (Sandbox Code Playgroud)


Bli*_*ndy 5

为了便于阅读,我会选择第一个选项,并注意您应首先实现列表,否则您将丢失在下一行中尝试选择的项目:

var sublist = list.Where(x => x.Condition).ToArray();
list.RemoveAll(x => x.Condition);
Run Code Online (Sandbox Code Playgroud)

第二个例子是O(n ^ 2)无缘无故,最后一个是完美的,但可读性较差.

编辑:现在我重读了你的最后一个例子,请注意,因为它现在写的将取出所有其他项目.您错过了条件检查,删除行实际上应该是list.RemoveAt(i--);因为第i+1th i个元素在删除后成为第th个元素,并且当您增加时,i您正在跳过它.

  • 当您对集合运行linq查询时,您不会返回一个数组,当您迭代它时,您会返回一个对象*您运行实际选择.拿你的第一个例子吧.`subList`只是一个对象,你从主数组中删除项目,然后当你执行'foreach(在subList中的var项)时,你什么都没回来,因为条件总是返回false. (3认同)

小智 5

第一个选项很好,但它会在集合上运行两次。您可以通过执行谓词内的附加逻辑来一次性完成此操作:

        var removedItems = new List<Example>();
        list.RemoveAll(x =>
        {
            if (x.Condition)
            {
                removedItems.Add(x);
                return true;
            }

            return false;
        });
Run Code Online (Sandbox Code Playgroud)

为了方便起见,您还可以将其包装到扩展中:

public static class ListExtensions
{
    public static int RemoveAll<T>(this List<T> list, Predicate<T> predicate, Action<T> action)
    {
        return list.RemoveAll(item =>
        {
            if (predicate(item))
            {
                action(item);
                return true;
            }

            return false;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用:

        var removedItems = new List<Example>();
        list.RemoveAll(x => x.Condition, x => removedItems.Add(x));
Run Code Online (Sandbox Code Playgroud)