Remove Matching Items from a List Using LINQ and Lambda

Removing items from one list that exist in another seems to be one of a developer’s life’s constants so I thought I’d write a short post showing how to carry out this task with the least amount of lines of code.

Let’s say, for example, that we have two lists of Person objects. One containing a list of 10 Person objects and another containing a list of 6 Person objects that we need to remove from the first list. You’re code might look something like this (but hopefully it won’t as you won’t be working with hard coded values):

Person p1 = new Person() { ID = 1, Forename = "Craig", Surname = "Bousie" };
Person p2 = new Person() { ID = 2, Forename = "Dave", Surname = "Smith" };
Person p3 = new Person() { ID = 3, Forename = "Craig", Surname = "Brown" };
Person p4 = new Person() { ID = 4, Forename = "Craig", Surname = "Buchanan" };
Person p5 = new Person() { ID = 5, Forename = "Graham", Surname = "Smith" };
Person p6 = new Person() { ID = 6, Forename = "Wendy", Surname = "Smith" };
Person p7 = new Person() { ID = 7, Forename = "Travis", Surname = "Bickle" };
Person p8 = new Person() { ID = 8, Forename = "Craig", Surname = "Smith" };
Person p9 = new Person() { ID = 9, Forename = "Jack", Surname = "Torrance" };
Person p10 = new Person() { ID = 10, Forename = "Danny", Surname = "Torrance" };

List<Person> myPeople = new List<Person> { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10 };
List<Person> myListOfPeopleToRemove = new List<Person> { p1, p3, p4, p7, p9, p10 };

Now you might just think okay I’ll loop through the myListOfPeopleToRemove list and check if the current object exists within the myPeople list and if it does I’ll remove it. Something like this:

foreach (Person p in myPeople)
   if (myPeople.Contains(p))

Now there’s nothing wrong with doing this. I’ve written code similar to this many times over the years and it’s perfectly fine. However, it’s possible to do this in other, more compact (and yes, maybe less readable) ways using a mixture of LINQ and Lambda expressions.

One option might be to remove all the Person objects from myPeople that exist in myListOfPeopleToRemove by matching on the surname. See this msdn article for more on the .Any method.

// Remove all by matching surnames
myPeople.RemoveAll(x => myListOfPeopleToRemove.Any(y => y.Surname == x.Surname));

Or you might want to remove all instances where the objects match. As per the comment we’re only able to do this as the lists we’re working with contain the same object instances as opposed to different object instances containing the same data. Be careful if you’re trying this as it may trip you up.

// Remove all by matching on the object (this works as the two lists contain the same objects as opposed
// to different object instances containing the same data - be careful with this)
myPeople.RemoveAll(x => myListOfPeopleToRemove.Contains(x));

So there you go, a couple of examples showing how to remove items from one list that exist in another. Whether it makes the code easier to read though is another story…