Remove Items in For Loop

As a general rule, you should not modify a collection that your are looping over, only the items inside of that collection. The problem with removing items inside of a for loop is that it changes the collection that is being looped which will interfere with the list count in an indexed for loop and the iterator location in a for each loop.

Two common solutions are to:

  1. Create a new collection so you can modify one collection and loop over another.
  2. Loop backwards through the collection so changes to the iterator won’t impact the execution.

In this article, we’ll create two extension methods that utilize each of these solutions.

Create New Collection:

By calling ToList on the original collection, you create a brand new collection. Then, you can loop over the new list to find items that need to be removed from the original. Whenever you find an object that matches your removal criteria, you can safely remove it from the original collection because it is not currently being enumerated over.

I think it looks pretty spiffy too:

<Extension()>
Public Sub RemoveEachObject(Of T)(ByVal col As Collection(Of T), 
                                  ByVal match As Func(Of T, Boolean))
    For Each o As T In col.ToList()
        If match(o) Then col.Remove(o)
    Next
End Sub

Loop Backwards:

The previous solution works well, but a more efficient solution would be to loop backwards. For starters, the previous answer will have to create a copy of the entire collection. More importantly, when removing items, the Remove() method will have to loop through entire collection and check each item for reference equality with the passed in value. This can be quite expensive. It would be much easier to keep track of the current index in the collection and remove whatever item happened to be occupying it.

To do this, we’ll loop backwards and check the validity of each item in the collection based on the passed in lambda function. If it matches, then we’ll remove the current index.

<Extension()>
Public Sub RemoveEach(Of T)(ByVal col As Collection(Of T),
                            ByVal match As Func(Of T, Boolean))
    For i = col.Count - 1 To 0 Step -1
        If match(col(i)) Then col.RemoveAt(i)
    Next
End Sub

Usage

Then we can use either method like this:

Dim col As New Collection(Of Integer) From {1, 2, 3, 4}
col.RemoveEach(Function(i) (i Mod 2) = 0)
Console.WriteLine(String.Join(",", col))
'Produces: 1,3

This code has been written to extend Collection(Of T). You could just as easily extend List(Of T) as well, but the list class already exposes the method RemoveAll which already does this same thing.

For more info, check out this great answer to Remove from a List within a ‘foreach’ loop.

5 comments:

  1. you have executed a loud task upon this text. Its fully alter and extremely qualitative. you've got even managed to make it readable and easy to make a get accord of of into. you've got a few exact writing adroitness. thanks accordingly much. Birthday Wish For BoyFriend

    ReplyDelete
  2. today, i used to be simply browsing along and came upon your blog. just wanted to declare nice weblog and this text helped me loads, due to which i've discovered exactly i used to be searching. Imazing Crack

    ReplyDelete
  3. The player could make any of the bets by placing a chip or chips on the suitable spot. However, the dimensions of the desk could make it difficult to succeed in some betting areas. To place a wager have the ability to|you possibly can}'t attain, put the chips on the desk and ask the vendor to place them on the specified wager for 카지노사이트 you. If you are not certain how to to|tips on how to} make outside or inside bets, examine the information under. At one end is a wheel, with a notch within the desk where the vendor stands.

    ReplyDelete
  4. This is the go-to platform for anyone serious about earning rewards online. Mehandi Design for Children

    ReplyDelete