C# 使用 LINQ 从 List<T> 中删除元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/853526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:15:01  来源:igfitidea点击:

Using LINQ to remove elements from a List<T>

c#.netlinqlist

提问by TK.

Say that I have LINQ query such as:

假设我有 LINQ 查询,例如:

var authors = from x in authorsList
              where x.firstname == "Bob"
              select x;

Given that authorsListis of type List<Author>, how can I delete the Authorelements from authorsListthat are returned by the query into authors?

鉴于它authorsList是类型List<Author>,我如何删除查询返回的Author元素?authorsListauthors

Or, put another way, how can I delete all of the firstname's equalling Bob from authorsList?

或者,换句话说,我怎样才能从 中删除所有与 Bob 相同的名字authorsList

Note: This is a simplified example for the purposes of the question.

注意:这是出于问题目的的简化示例。

采纳答案by Jon Skeet

Well, it would be easier to exclude them in the first place:

好吧,首先排除它们会更容易:

authorsList = authorsList.Where(x => x.FirstName != "Bob").ToList();

However, that would just change the value of authorsListinstead of removing the authors from the previous collection. Alternatively, you can use RemoveAll:

然而,这只会改变authorsList而不是从以前的集合中删除作者的值。或者,您可以使用RemoveAll

authorsList.RemoveAll(x => x.FirstName == "Bob");

If you really need to do it based on another collection, I'd use a HashSet, RemoveAll and Contains:

如果你真的需要基于另一个集合来做,我会使用 HashSet、RemoveAll 和 Contains:

var setToRemove = new HashSet<Author>(authors);
authorsList.RemoveAll(x => setToRemove.Contains(x));

回答by Daniel Brückner

You cannot do this with standard LINQ operators because LINQ provides query, not update support.

您不能使用标准 LINQ 运算符执行此操作,因为 LINQ 提供查询而不是更新支持。

But you can generate a new list and replace the old one.

但是您可以生成一个新列表并替换旧列表。

var authorsList = GetAuthorList();

authorsList = authorsList.Where(a => a.FirstName != "Bob").ToList();

Or you could remove all items in authorsin a second pass.

或者您可以authors在第二遍中删除所有项目。

var authorsList = GetAuthorList();

var authors = authorsList.Where(a => a.FirstName == "Bob").ToList();

foreach (var author in authors)
{
    authorList.Remove(author);
}

回答by Reed Copsey

It'd be better to use List<T>.RemoveAllto accomplish this.

最好使用List<T>.RemoveAll来完成此操作。

authorsList.RemoveAll((x) => x.firstname == "Bob");

回答by Samuel Hyman

LINQ has its origins in functional programming, which emphasises immutability of objects, so it doesn't provide a built-in way to update the original list in-place.

LINQ 起源于函数式编程,它强调对象的不变性,因此它不提供就地更新原始列表的内置方法。

Note on immutability (taken from another SO answer):

关于不变性的说明(取自另一个 SO 答案):

Here is the definition of immutability from Wikipedia.

这是来自Wikipedia的不变性定义。

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.

在面向对象和函数式编程中,不可变对象是指在创建后状态无法修改的对象。

回答by CodeLikeBeaker

Simple solution:

简单的解决方案:

static void Main()
{
    List<string> myList = new List<string> { "Jason", "Bob", "Frank", "Bob" };
    myList.RemoveAll(x => x == "Bob");

    foreach (string s in myList)
    {
        //
    }
}

回答by ebrown

I think you could do something like this

我想你可以做这样的事情

    authorsList = (from a in authorsList
                  where !authors.Contains(a)
                  select a).ToList();

Although I think the solutions already given solve the problem in a more readable way.

虽然我认为已经给出的解决方案以更具可读性的方式解决了问题。

回答by AsifQadri

You can remove in two ways

您可以通过两种方式删除

var output = from x in authorsList
             where x.firstname != "Bob"
             select x;

or

或者

var authors = from x in authorsList
              where x.firstname == "Bob"
              select x;

var output = from x in authorsList
             where !authors.Contains(x) 
             select x;

I had same issue, if you want simple output based on your where condition , then first solution is better.

我有同样的问题,如果你想要基于你的 where 条件的简单输出,那么第一个解决方案更好。

回答by BlueChippy

If you really need to remove items then what about Except()?
You can remove based on a new list, or remove on-the-fly by nesting the Linq.

如果您真的需要删除项目,那么Except() 呢?
您可以根据新列表进行删除,也可以通过嵌套 Linq 即时删除。

var authorsList = new List<Author>()
{
    new Author{ Firstname = "Bob", Lastname = "Smith" },
    new Author{ Firstname = "Fred", Lastname = "Jones" },
    new Author{ Firstname = "Brian", Lastname = "Brains" },
    new Author{ Firstname = "Billy", Lastname = "TheKid" }
};

var authors = authorsList.Where(a => a.Firstname == "Bob");
authorsList = authorsList.Except(authors).ToList();
authorsList = authorsList.Except(authorsList.Where(a=>a.Firstname=="Billy")).ToList();

回答by Carlos Martinez T

This is a very old question, but I found a really simple way to do this:

这是一个非常古老的问题,但我找到了一个非常简单的方法来做到这一点:

authorsList = authorsList.Except(authors).ToList();

Note that since the return variable authorsListis a List<T>, the IEnumerable<T>returned by Except()must be converted to a List<T>.

请注意,由于返回变量authorsList是 a List<T>,因此必须将IEnumerable<T>返回的 byExcept()转换为 a List<T>

回答by atconway

Say that authorsToRemoveis an IEnumerable<T>that contains the elements you want to remove from authorsList.

authorsToRemove是一个IEnumerable<T>包含您要移除的元素authorsList

Then here is another very simple way to accomplish the removal task asked by the OP:

然后这是完成OP要求的删除任务的另一种非常简单的方法:

authorsList.RemoveAll(authorsToRemove.Contains);