我试图弄清楚如何遍历要从另一个项目列表中删除的通用项目列表。
所以假设我有这个作为一个假设的例子
List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
我想用 foreach 遍历 list1 并删除 List1 中的每个项目,该项目也包含在 List2 中。
我不太确定如何去做,因为 foreach 不是基于索引的。
list1
中删除 list2
中存在的项目,还是要从 list2
中删除 list1
中存在的项目?在发表此评论时,提供的每个答案都将执行后者。
您可以使用 Except:
List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();
你可能甚至不需要那些临时变量:
List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();
请注意,Except
不会修改任何一个列表 - 它会使用结果创建一个新列表。
您不需要索引,因为 List<T>
类允许您按值而不是使用 Remove
函数的索引来删除项目。
foreach(car item in list1) list2.Remove(item);
list2.Remove(item);
语句周围使用方括号。
list1.ForEach(c => list2.Remove(c));
在我的例子中,我有两个不同的列表,有一个共同的标识符,有点像外键。 “nzrytmn”引用的第二种解决方案:
var result = list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
是最适合我情况的那个。我需要在没有已注册记录的情况下加载 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();
我建议使用 LINQ extension methods。您可以使用一行代码轻松完成,如下所示:
list2 = list2.Except(list1).ToList();
这当然是假设您从 list2 中删除的 list1 中的对象是同一个实例。
list1.RemoveAll(l => list2.Contains(l));
O(N)
,这将导致 O(N^2)
,这可能是大型列表的问题。
您可以使用 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));
解决方案 1:您可以这样做:
List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();
但在某些情况下,此解决方案可能不起作用。如果它不起作用,您可以使用我的第二个解决方案。
解决方案 2:
List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
我们假设 list1 是您的主列表,而 list2 是您的次要列表,并且您想要获取 list1 的项目而没有 list2 的项目。
var result = list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
由于 Except
不修改列表,您可以在 List<T>
上使用 ForEach:
list2.ForEach(item => list1.Remove(item));
它可能不是最有效的方法,但它很简单,因此可读,并且它会更新原始列表(这是我的要求)。
我认为将列表 A 转换为字典然后 foreach 第二个列表并调用 DictA.Remove(item)
会很快,否则我认为大多数解决方案将导致通过列表 A 直接或在幕后进行多次迭代。
如果列表很小,则可能无关紧要。
给你吧。。
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);
}
});
IEnumerable<car>
,而不是List<car>
。您需要调用ToList()
来获取列表。另外,我认为应该是GetSomeOtherList().Except(GetTheList()).ToList()
using System.Linq;
,您还需要它。Except
时要小心,因为它实际上执行了一个 set 操作,它区分了结果列表。我没有预料到这种行为,因为我使用的是List
,而不是HashSet
。 Related.