Removing Collection Elements During Enumeration

270 words.

Another in a series of random programming tips by Thomas Krehbiel, mostly to help me remember them in the future.

I run into this quite often. If you are working with a “managed” language (.NET or Java), and you find yourself in a situation where you need to remove elements from a collection while you are simultaneously enumerating over the collection, you’ll run into a problem. Consider this C# example:

ArrayList collection;
foreach( object enumeratedObject in collection )
  if( ObjectShouldBeRemoved( enumeratedObject ) ) collection.Remove( enumeratedObject );

The seemingly straight-forward code above will fail because the enumeration state will become invalid after you alter the collection.

There are (at least) two approaches for working around the problem:

Method 1. Create a copy of the collection and enumerate the copy.

Method 2. Place the items you want to remove in a second collection, then remove them after the enumeration is finished.

The first method is simple and good for most situations:

ArrayList collection;
ArrayList collectionCopy = new ArrayList( collection );
foreach( object enumeratedObject in collectionCopy )
  if( ObjectShouldBeRemoved( enumeratedObject ) ) collection.Remove( enumeratedObject );

I might use the second method for large collections where it would be excessively time- or memory-consuming to construct a complete copy of the original collection. Modern computers being what they are, however, this would probably be a rare case.

ArrayList collection;
ArrayList removalList = new ArrayList();
foreach( object enumeratedObject in collection )
  if( ObjectShouldBeRemoved( enumeratedObject ) ) removalList.Add( enumeratedObject );
foreach( object o in removeList )
  collection.Remove( o );

The same methods can be used if you need to add elements to a collection while enumerating it.

Related

This page is a static archival copy of what was originally a WordPress post. It was converted from HTML to Markdown format before being built by Hugo. There may be formatting problems that I haven't addressed yet. There may be problems with missing or mangled images that I haven't fixed yet. There may have been comments on the original post, which I have archived, but I haven't quite worked out how to show them on the new site.

Sorry, new comments are disabled on older posts. This helps reduce spam. Active commenting almost always occurs within a day or two of new posts.