Hi there.
I'm trying to remove a item from a ArrayList and I get this Exception:
Collection was modified; enumeration operation may not execute.
Any ideas? thanks for the help
views:
593answers:
5
+1
A:
Don't modify the list inside of a loop which iterates through the list.
David Lively
2010-01-07 22:33:16
Snap! So, how should i be doing it?
Ricardo
2010-01-07 22:33:56
Use a regular loop instead (for/while). The problem is using a 'foreach' statement (i.e. an enumerator).
Noon Silk
2010-01-07 22:34:45
@silky f you're using a for() or while() to iterate through the collection, be sure to do it from the back/top - starting at collection.count-1 and going down to 0. Otherwise you'll hit the same problem.
David Lively
2010-01-23 07:35:02
+19
A:
You are removing the item during a foreach
, yes? Simply, you can't. There are a few common options here:
- use
List<T>
andRemoveAll
with a predicate iterate backwards by index, removing matching items
for(int i = list.Count - 1; i >= 0; i--) { if({some test}) list.RemoveAt(i); }
use
foreach
, and put matching items into a second list; now enumerate the second list and remove those items from the first (if you see what I mean)
Marc Gravell
2010-01-07 22:34:22
if the collection isn't that big, a simple .ToArray() and enumerating that instead might be good enough as well.
Lasse V. Karlsen
2010-01-07 22:36:42
That's pretty neat, ive always been iterating forwards and conditionally decrementing `i` so that next time it increments it will point to the item after the deleted one. This avoids the extra step.
Igor Zevaka
2010-01-07 22:57:55
Backwards iteration works fine. I'd avoid using .ToArray() as it adds an unnecessary loop to your algorithm (one to copy the list to an array, one to remove the items you're interested in).
David Lively
2010-01-08 17:50:07
@Rob - not *must*, but it is trickier if you go forwards; more ways to get it wrong and end up off-by-one.
Marc Gravell
2010-01-07 22:45:50
A:
One way is to add the item(s) to be deleted to a new list. Then go through and delete those items.
ozczecho
2010-01-07 22:35:41
+2
A:
Here's an example (sorry for any typos)
var itemsToRemove = new ArrayList(); // should use generic List if you can
foreach (var item in originalArrayList) {
if (...) {
itemsToRemove.Add(item);
}
}
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
OR if you're using 3.5, Linq makes the first bit easier:
itemsToRemove = originalArrayList
.Where(item => ...)
.ToArray();
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
Replace "..." with your condition that determines if item should be removed.
Will
2010-01-07 22:46:47
If you're using "generic List" (which I interpret as `List<T>`) then just use `list.RemoveAll(item => ...)`.
Marc Gravell
2010-01-07 23:26:32