Search code examples
c#listloopsgenericskey-value

How to remove elements from a generic list while iterating over it?


I am looking for a better pattern for working with a list of elements which each need processed and then depending on the outcome are removed from the list.

You can't use .Remove(element) inside a foreach (var element in X) (because it results in Collection was modified; enumeration operation may not execute. exception)... you also can't use for (int i = 0; i < elements.Count(); i++) and .RemoveAt(i) because it disrupts your current position in the collection relative to i.

Is there an elegant way to do this?


Solution

  • Iterate your list in reverse with a for loop:

    for (int i = safePendingList.Count - 1; i >= 0; i--)
    {
        // some code
        // safePendingList.RemoveAt(i);
    }
    

    Example:

    var list = new List<int>(Enumerable.Range(1, 10));
    for (int i = list.Count - 1; i >= 0; i--)
    {
        if (list[i] > 5)
            list.RemoveAt(i);
    }
    list.ForEach(i => Console.WriteLine(i));
    

    Alternately, you can use the RemoveAll method with a predicate to test against:

    safePendingList.RemoveAll(item => item.Value == someValue);
    

    Here's a simplified example to demonstrate:

    var list = new List<int>(Enumerable.Range(1, 10));
    Console.WriteLine("Before:");
    list.ForEach(i => Console.WriteLine(i));
    list.RemoveAll(i => i > 5);
    Console.WriteLine("After:");
    list.ForEach(i => Console.WriteLine(i));