Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ compare two lists and remove

Tags:

c#

linq

I have two lists. I want to remove any items from LIST1 that are NOT present in LIST2.

So for example:

        var list1 = new List<DownloadTask>();
        list1.Add(new DownloadTask{ OperationID = 1, MachineID = 1 });
        list1.Add(new DownloadTask{ OperationID = 2, MachineID = 1 });
        list1.Add(new DownloadTask{ OperationID = 3, MachineID = 1 });
        list1.Add(new DownloadTask{ OperationID = 3, MachineID = 2 });

        var list2 = new List<DownloadTask>();
        list2.Add(new DownloadTask{ OperationID = 1, MachineID = 1 });
        list2.Add(new DownloadTask{ OperationID = 3, MachineID = 2 });

After run list1 should contain only items: with combination operationId = 1, machineId = 1 AND OperationId = 3, MachineId =2.

like image 674
ShaneKm Avatar asked Jan 07 '13 07:01

ShaneKm


2 Answers

Does DownloadTask override Equals and GetHashCode correctly? If so, all you need is:

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

That's if you're happy to create a new list, of course. If you really want to remove them from the existing list, it's slightly harder. It would quite possibly be simplest to work out what the result should look like, then clear and re-add:

var newList = list1.Intersect(list2).ToList();
list1.Clear();
list1.AddRange(newList);

Of course, all of this does require you to implement equality appropriately in DownloadTask - but if you haven't done so already, it sounds like it would be a good idea to do so. (Or at least implement IEqualityComparer<DownloadTask> somewhere - you can pass a comparer to Intersect.)

As a side note, I view "only keep the elements in list1 which are also in list2" (i.e. intersection) as a simpler way of looking at the problem than "remove all elements from list1 which aren't in list2" - the latter is basically a double negative, which is always a bit of a pain.

like image 97
Jon Skeet Avatar answered Sep 26 '22 07:09

Jon Skeet


I think it should be:

list1.RemoveAll(x => list2.Exists(y => y.OperationID == x.OperationID && y.MachineID == x.MachineID));
like image 34
ShaneKm Avatar answered Sep 23 '22 07:09

ShaneKm