views:

399

answers:

6

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.

A: 

simple loop:

for (item i: LISTA) {
    removeItem(i, LISTB);
}


method removeItem(Item, List) {
    for (Item i: List) {
        if (Item == i)
            List.removeItem(i);
    }
}
Elie
A: 

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)
Matthew Brubaker
+11  A: 

Here are two options. Not sure which one is faster.

listB.RemoveAll(listA.Contains);


foreach (string str in listA.Intersect(listB))
  listB.Remove(str);
Todd White
A: 

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 }.

Marcus Griep
+2  A: 

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);
}
Microserf
+1  A: 

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

Barbaros Alp