Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# collection.RemoveAll(collection.OfType<type>());

Can I do something like this:

collection.RemoveAll(collection.OfType<type>());

To remove all the elements of a given type from a collection?

like image 951
alan2here Avatar asked Dec 02 '11 20:12

alan2here


4 Answers

Both of the already-submitted answers are correct, but omit an explanation why the poster's sample code doesn't work. A couple of interesting points:

First, RemoveAll() is not defined in the ICollection or ICollection<T> interface; it's defined on List<T>, for example, but the semantically equivalent method on HashSet<T> is called RemoveWhere(). If you want to be able to do this for any ICollection<T>, you should write an extension method.

Second, the question's sample code passes a sequence of items to be removed from the collection, but List<T>.RemoveAll() and HashSet<T>.RemoveWhere() take a predicate to identify the items to be removed (as shown in the other answers). You could write your extension method to take the other approach, and pass an IEnumerable<T> as in your example. You need to be careful, though, because you can't do this:

foreach (var item in collection)
    if (ShouldRemove(item))
        collection.Remove(item);

If you try to do that, you should get an InvalidInvalidOperationException with a message like "Collection was modified; enumeration operation may not execute."

like image 200
phoog Avatar answered Dec 14 '22 12:12

phoog


If I understand it correctly, you have a single collection of any object type and you want to remove all items of a type from that collection. If so, it's simple:

objects.RemoveAll(q=>q.GetType()==typeof(YourType));
like image 33
George Johnston Avatar answered Dec 14 '22 14:12

George Johnston


As the first two code answers use a List specifically, and the third only has nonworking code:

ICollection collection = GetCollection();
foreach (object obj in collection.Where(obj => obj is type).ToList())
     collection.Remove(obj);

You can end the enumeration by calling ToList, so that removal is allowed again. It's totally inefficient tho, as it requires one enumeration to get the objects and then removes them one by one, possibly requiring enumeration each time. If the collection type you're using has it's own methods, like List.RemoveAll, use those instead, but your use of "collection" implies you do not know its type.

Alternatively, if the importance is not on preserving the object, consider reassigning instead:

collection = collection.Where(obj => obj is type == false).ToList();
like image 45
Wolfzoon Avatar answered Dec 14 '22 12:12

Wolfzoon


I would do something like this:

collection.RemoveAll(i => collection.OfType().Contains(i));


EDIT:
 collection.RemoveAll(i => i is type);
like image 29
Joe Avatar answered Dec 14 '22 13:12

Joe