从另一个列表中删除项目

Pos*_*Guy 181 .net c# list

我正在试图弄清楚如何遍历我想要从另一个项目列表中删除的项目的通用列表.

所以我要说这是一个假设的例子

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
Run Code Online (Sandbox Code Playgroud)

我想用foreach遍历list1并删除List1中也包含在List2中的每个项目.

由于foreach不是基于索引的,我不太清楚如何去做.

Mar*_*ers 326

您可以使用:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();
Run Code Online (Sandbox Code Playgroud)

你可能甚至不需要那些临时变量:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,Except不会修改任何列表 - 它会创建一个包含结果的新列表.

  • 小点,但这会产生一个`IEnumerable <car>`,而不是一个`List <car>`.你需要调用`ToList()`来获取一个列表.另外,我认为它应该是`GetSomeOtherList().除了(GetTheList()).ToList()` (11认同)
  • 你还需要`using System.Linq;`如果你以前没有. (7认同)
  • 为什么这是正确的答案?当然这可能会在你的上下文中给你你想要的东西,但是,"从另一个列表中删除项目"肯定不等同于设置差异操作,你不应该通过接受这个作为正确答案来误导人们! (3认同)
  • 使用`Except`时要小心,因为这实际上执行了**set**操作,它区分了结果列表.我并没有期待这种行为,因为我使用的是`List`,而不是`HashSet`.[相关.](http://stackoverflow.com/questions/2975944/except-has-similar-effect-to-distinct) (2认同)

Ada*_*son 31

您不需要索引,因为List<T>该类允许您通过值删除项目而不是使用该Remove函数索引.

foreach(car item in list1) list2.Remove(item);
Run Code Online (Sandbox Code Playgroud)

  • @uriz @AdamRobinson,因为我们正在讨论优雅的解决方案......`list1.ForEach(c => list2.Remove(c));` (4认同)
  • +1,但IMO你应该在`list2.Remove(item);`语句周围使用括号. (2认同)
  • @sr pt:我总是在出现在另一行的语句上使用括号,但不能在我可以/确实放在与流控制语句相同的行上的单语句块上. (2认同)
  • 只要你保持一致,是否使用括号并不重要.. IMO :) (2认同)
  • @uriz:无视优雅的资格,这是唯一的答案实际上做的问题*说*(删除主列表中的项目); 另一个答案会创建一个*new*列表,如果列表是从期望修改而不是获取替换列表的其他调用者传入的,则可能不需要这样. (2认同)

Ber*_*ire 22

我建议使用LINQ扩展方法.您可以使用一行代码轻松完成此操作:

list2 = list2.Except(list1).ToList();
Run Code Online (Sandbox Code Playgroud)

当然,假设您从list2中删除的list1中的对象是同一个实例.

  • 它也删除了重复项. (2认同)

Gab*_*eis 16

在我的情况下,我有两个不同的列表,有一个公共标识符,有点像外键."nzrytmn"引用的第二个解决方案:

var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
Run Code Online (Sandbox Code Playgroud)

是最符合我情况的那个.我需要加载一个没有已经注册的记录的DropDownList.

谢谢 !!!

这是我的代码:

t1 = new T1();
t2 = new T2();

List<T1> list1 = t1.getList();
List<T2> list2 = t2.getList();

ddlT3.DataSource= list2.Where(s => !list1.Any(p => p.Id == s.ID)).ToList();
ddlT3.DataTextField = "AnyThing";
ddlT3.DataValueField = "IdAnyThing";
ddlT3.DataBind();
Run Code Online (Sandbox Code Playgroud)


Joã*_*elo 13

你可以使用LINQ,但我会选择RemoveAll方法.我认为那是更能表达你意图的那个.

var integers = new List<int> { 1, 2, 3, 4, 5 };

var remove = new List<int> { 1, 3, 5 };

integers.RemoveAll(i => remove.Contains(i));
Run Code Online (Sandbox Code Playgroud)

  • 或者甚至更简单的方法组你可以做 - integers.RemoveAll(remove.Contains); (7认同)

Ale*_*tro 11

list1.RemoveAll(l => list2.Contains(l));
Run Code Online (Sandbox Code Playgroud)

  • 由于两种列表方法都是“O(N)”,这将导致“O(N^2)”,这可能是大型列表的问题。 (2认同)

nzr*_*tmn 5

解决方案1:您可以这样做:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();
Run Code Online (Sandbox Code Playgroud)

但在某些情况下,这种解决方案可能无效.如果它不起作用,你可以使用我的第二个解决方案.

解决方案2:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
Run Code Online (Sandbox Code Playgroud)

我们假装list1是你的主列表,list2是你的二次列表,你想得到list1的项目而没有list2的项目.

 var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
Run Code Online (Sandbox Code Playgroud)