Reputation: 2433
I've got two collections (generic Lists), let's call them ListA and ListB.
In ListA I've got a few items of type A. In ListB I've got some items of type B that have the SAME ID (but not same type) as the items in ListA, plus many more. I want to remove all the items from ListB that have the same ID as the ones in ListA. What's the best way of doing this? Is Linq to objects a nice fit? What algorithm would you use?
Example
ListA: ItemWithID1, ItemWithID2¨
ListB: ItemWithID1, ItemWithID2, ItemWithID3, ItemWithID4
EDIT: I forgot to mention in my original question that ListA and ListB doesn't contain the same types. So the only way to compare them is through the .Id property. Which invalidates the answers I've gotten so far.
Upvotes: 5
Views: 4294
Reputation: 6434
I think the best suitable method is Microserf's
Most of the examples above are for the situations which the two lists are the same type. But if you want to compare different types Id and want to delete themn best way is Microserf's way.
Thanks
Upvotes: 1
Reputation: 2433
I discovered that lambda expressions was a perfect match. Instead of a long linq to objects method, I could do it in just a few lines with lambda:
foreach(TypeA objectA in listA){
listB.RemoveAll(objectB => objectB.Id == objectA.Id);
}
Upvotes: 3
Reputation: 8424
Something for reference that is available with the C5 Generic Collection Library for .NET is the RemoveAll
method, just as specified by Todd White before. However, C5 also offers another method in its interfaces, RetainAll
which does the functional opposite of RemoveAll
in that, using the original author's lists,
ListB.RetainAll(ListA)
is the set { Item1, Item2 }
, whereas ListB.RemoveAll(ListA)
is the set { Item3, Item4 }
.
Upvotes: 0
Reputation: 7890
Here are two options. Not sure which one is faster.
listB.RemoveAll(listA.Contains);
foreach (string str in listA.Intersect(listB))
listB.Remove(str);
Upvotes: 12
Reputation: 3117
I don't know that it's the best option, but if you are removing all elements of ListA that are in ListB, simply iterating over ListA and using an if ListB.contains construct, removing it from ListB.
Something like this
foreach Object o in ListA
If ListB.contains(o)
ListB.remove(o)
Upvotes: 0
Reputation: 13855
simple loop:
for (item i: LISTA) {
removeItem(i, LISTB);
}
method removeItem(Item, List) {
for (Item i: List) {
if (Item == i)
List.removeItem(i);
}
}
Upvotes: 0