Remove items from one list in another
我正在试图找出如何遍历一个通用的项目列表,我想从另一个项目列表中删除这些项目。
所以假设我有一个假设的例子
1 2
| List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList(); |
我想用foreach遍历列表1,并删除列表1中也包含在列表2中的每个项。
我不太确定该怎么做,因为foreach不是基于索引的。
- 是否要删除列表1中也在列表2中的项?
- 您需要从列表1中删除项目并将其添加到列表2或其他内容?
- 相关:stackoverflow.com/questions/2477633/&hellip;
- 如果您有list1=foo1和list2=foo1,foo1,会发生什么。应该从列表2中删除foo1的所有副本,还是只删除第一个副本?
- -我对这个问题的每一个答案都投了反对票,因为我认为他们都错了,但问题似乎只是被问得很糟糕。现在,我无法改变它们-抱歉。您想从list2中删除list1中的项目,还是要从list2中删除list1中的项目?在评论时,所提供的每个答案都将执行后者。
- @约翰·拉什奇,你应该少一点对那些落选感到高兴。有些答案是相当概念性的,只演示了如何实现OP想要的,甚至不涉及问题中提到的列表。
- @约翰·拉什:我必须同意乔&227;o-如果答案有一个小问题,但这是一个很好的建议,请在评论中指出。一个正确的答案不应该因为一个小错误而被否决,只要原则是正确的。当你投反对票时,在评论中解释为什么会让人们困惑,为什么他们的答案被投反对票。当我第一次读到这个问题的时候,我犯了同样的错误,错误的回答了,但是有两个人很友好地指出了我的错误,所以我把它改正了。
- @马克-你是对的,完全是我的错-这就是为什么我把评论放在这里解释发生了什么,我在寻找以前的答案,我在投票后已经有了一个类似的问题,我发现后会留下评论-结果这不是最好的过程!
您可以使用,除了:
1 2 3
| List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList(); |
您可能甚至不需要这些临时变量:
1
| List<car> result = GetSomeOtherList().Except(GetTheList()).ToList(); |
注意,Except不修改任何一个列表—它用结果创建一个新的列表。
- 小点,但这将产生一个IEnumerable,而不是一个List。你需要打电话给ToList()才能得到一份清单。另外,我认为应该是GetSomeOtherList().Except(GetTheList()).ToList()。
- 如果你以前没有,你也需要使用using System.Linq;。
- 我已经使用system.linq添加了,但我仍然无法访问,除非。但在我的例子中,我使用的是数组列表。关于如何使它与ArrayList一起工作有什么想法吗?
- 注:list1.except(list2)的结果与list2.except(list1)的结果不同。最后一个为我工作。
- 使用Except时要小心,因为它实际上执行了一个集合操作,它区分了结果列表。我没有预料到这种行为,因为我使用的是List,而不是HashSet。相关的。
- 为什么这是正确的答案?当然,这可能会给您在您的上下文中想要的,但是,"从一个列表中删除另一个列表中的项目"肯定不等同于设置差异操作,并且您不应该通过接受它作为正确的答案来误导人们!!!!!
您不需要索引,因为List类允许您按值删除项目,而不是使用Remove函数删除索引。
1
| foreach(car item in list1) list2.Remove(item); |
- +1,但在我看来,你应该在list2.Remove(item);语句周围加括号。
- @sr pt:我总是在出现在另一行的语句上使用括号,但不能在单个语句块上使用括号,因为我可以/确实将其放在与流控制语句相同的行上。
- 只要你始终如一,用括号还是不用括号都没关系。国际海事组织:
- @亚当:我同意,但也许我不会让它成为一条直线。事实上,我更喜欢你的解决方案,而不是最有投票权的方案——它更简单,更容易阅读,这总是一个优点。
- 同意——我更喜欢这个,因为它改变了现有的列表,而不是创建一个新的列表,而且我也不会使它成为一个行程序。
- 这不是一个优雅的解决方案。使用.except()(参见答案)
- @罗西:不管什么是优雅的,这是唯一一个真正做到了问题的答案(删除了主列表中的项目);另一个答案创建了一个新的列表,如果列表是从另一个期望它被修改而不是得到回复的调用者传入,这可能是不可取的。赔偿清单
- @亚当·罗宾逊,你是对的,但我不确定这个问题是朝着这个方向发展的(不是创建另一个列表…)
- @我想说的是,你可能是正确的答案,但因为这不仅仅是为了回答提问者的问题(这也是为了建立一个知识库,让其他人可以搜索答案),所以我想以回答问题的方式回答问题。
- @既然我们在讨论优雅的解决方案…list1.ForEach(c => list2.Remove(c));
- "优雅"应该意味着"坚持维护这段代码的开发人员会发现它简单易懂",这就是为什么这是最好的答案。
我建议使用LINQ扩展方法。你可以用这样的一行代码很容易做到:
1
| list2 = list2.Except(list1).ToList(); |
这当然是假设您要从列表2中删除的列表1中的对象是相同的实例。
在我的例子中,我有两个不同的列表,有一个公共标识符,有点像一个外键。"nzrytmn"引用的第二个解决方案:
1
| var result = list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList(); |
最适合我的情况。我需要加载一个没有已注册记录的DropDownlist。
谢谢您!!!!
这是我的代码:
1 2 3 4 5 6 7 8 9 10
| 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(); |
你可以使用linq,但我会使用RemoveAll方法。我认为这是一个更好地表达你的意图。
1 2 3 4 5
| var integers = new List <int> { 1, 2, 3, 4, 5 };
var remove = new List <int> { 1, 3, 5 };
integers .RemoveAll(i => remove.Contains(i )); |
- 或更简单的方法组,你可以做-整数.removeall(remove.contains);
1
| list1.RemoveAll(l => list2.Contains(l)); |
- A.K.A."完全不纯":—)
- 怎么了?它看起来比使用except创建另一个列表更好。尤其是当两个列表都很小的时候。
解决方案1:您可以这样做:
1
| List<car> result = GetSomeOtherList().Except(GetTheList()).ToList(); |
但在某些情况下,这种解决方案可能不起作用。如果它不起作用,你可以使用我的第二个解决方案。
解决方案2:
1 2
| List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList(); |
我们假设list1是您的主列表,list2是您的第二个列表,并且您希望得到不包含list2项的list1项。
1
| var result = list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList(); |
来吧…
1 2 3 4 5 6 7 8 9 10
| List <string> list = new List <string>() {"1", "2", "3" };
List <string> remove = new List <string>() {"2" };
list .ForEach(s =>
{
if (remove.Contains(s ))
{
list .Remove(s );
}
}); |
- - 1。这将在删除第一个项后引发异常。此外,遍历要删除的列表(通常)是一个更好的主意,因为它通常较小。您还强制进行更多的列表遍历。