VB.NET Collections – Iterate While Removing Elements

collectionsvb.net

I am iterating over a collection and want to delete some entries of it. Example:

For i = 0 To Node.Nodes.Count
    If i >= args.TotalNumberOfNodes Then
        Node.Nodes.RemoveAt(i)
    End If
Next i

As you can see, if one condition is true, I want to delete the item from the collection. If I pass now a List of 20 items into this, what happens is that every 2nd element gets deleted for an obvious reason: If the item should be removed, it gets removed which decreases the list size by 1 and then i is incremented by one which leaves the then current element out.

Another (working) approach is:

For i = 0 To Node.Nodes.Count
    If i >= args.TotalNumberOfNodes Then
        Node.Nodes.RemoveAt(i)
        i = i - 1
    End If
Next i

This technique decrements i by 1 before it gets incremented at the end of the for loop resulting in the same i as before. Since this seems to me a bit like bad design and it is not completely easy to understand for readers, I would like to know if there is any better way to remove items from a list but not skipping the next item from this list.

In addition to this, with a for each loop it throws me an exception because it tries to iterate over the list which is currently being altered. On a different posting, I saw the approach of adding all to a new list and then using a removeAll method. This would work technically but for performance reasons I would like to manipulate the list as I walk over it.

Best Answer

Since lists grow and shrink from their end, you can easily solve the problem by simply looping over the list in reverse order.

For i = Node.Nodes.Count-1 To 0 Step -1
    If SomeCondition Then
        Node.Nodes.RemoveAt(i)
    End If
Next i
Related Topic