Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete inside foreach with linq where

Tags:

c#

.net

linq

where

I can see why this is not allowed:

foreach (Thing t in myCollection) {
   if (shouldDelete(t) {
      myCollection.Delete(t);
   }
}

but how about this?

foreach (Thing t in myCollection.Where(o=>shouldDelete(o)) {
   myCollection.Delete(t);
}

I don't understand why this fails. The "Where()" method obviously isn't returning the original collection, so I am not enumerating round the original collection when I try to remove something from it.

like image 441
Andy Avatar asked Apr 16 '12 13:04

Andy


3 Answers

Try use this code

myCollection.RemoveAll(x => x.shouldDelete(x));
like image 73
Likurg Avatar answered Nov 14 '22 17:11

Likurg


I don't understand why this fails.

I assume your question then is "why does this fail?" (You forgot to actually ask a question in your question.)

The "Where()" method obviously isn't returning the original collection

Correct. "Where" returns an IEnumerable<T> which represents the collection with a filter put on top of it.

so I am not enumerating round the original collection when I try to remove something from it.

Incorrect. You are enumerating the original collection. You're enumerating the original collection with a filter put on top of it.

When you call "Where" it does not eagerly evaluate the filter and produce a brand new copy of the original collection with the filter applied to it. Rather, it gives you an object which enumerates the original collection, but skips over the items that do not match the filter.

When you're at a store and you say "show me everything", the guy showing you everything shows you everything. When you say "now just show me the apples that are between $1 and $5 a kilogram", you are not constructing an entirely new store that has only apples in it. You're looking at exactly the same collection of stuff as before, just with a filter on it.

like image 26
Eric Lippert Avatar answered Nov 14 '22 15:11

Eric Lippert


You can do:

myCollection.RemoveAll(shouldDelete);
like image 9
Scroog1 Avatar answered Nov 14 '22 17:11

Scroog1