简体   繁体   中英

Remove items from one list in another

I'm trying to figure out how to traverse a generic list of items that I want to remove from another list of items.

So let's say I have this as a hypothetical example

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

I want to traverse list1 with a foreach and remove each item in List1 which is also contained in List2.

I'm not quite sure how to go about that as foreach is not index based.

You can use Except :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();

You probably don't even need those temporary variables:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

Note that Except does not modify either list - it creates a new list with the result.

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

foreach(car item in list1) list2.Remove(item);

I would recommend using the LINQ extension methods . You can easily do it with one line of code like so:

list2 = list2.Except(list1).ToList();

This is assuming of course the objects in list1 that you are removing from list2 are the same instance.

In my case I had two different lists, with a common identifier, kind of like a foreign key. The second solution cited by "nzrytmn" :

var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

Was the one that best fit in my situation. I needed to load a DropDownList without the records that had already been registered.

Thank you !!!

This is my code:

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();

You could use LINQ, but I would go with RemoveAll method. I think that is the one that better expresses your intent.

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

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

integers.RemoveAll(i => remove.Contains(i));
list1.RemoveAll(l => list2.Contains(l));

Solution 1 : You can do like this :

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

But in some cases may this solution not work. if it is not work you can use my second solution .

Solution 2 :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

we pretend that list1 is your main list and list2 is your secondry list and you want to get items of list1 without items of list2.

 var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

As Except does not modify the list, you can use ForEach on List<T> :

list2.ForEach(item => list1.Remove(item));

It may not be the most efficient way, but it is simple, therefore readable, and it updates the original list (which is my requirement).

I think it would be quick to convert list A to a dictionary and then foreach the second list and call DictA.Remove(item) otherwise I think most solutions will cause many iterations through list A either directly or under the covers.

If the lists are small, it probably won't matter.

Here ya go..

    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);
            }
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM