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

前端 未结 27 2950
忘了有多久
忘了有多久 2020-11-21 22:48

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

27条回答
  •  猫巷女王i
    2020-11-21 23:36

    Using Remove or RemoveAt on a list while iterating over that list has intentionally been made difficult, because it is almost always the wrong thing to do. You might be able to get it working with some clever trick, but it would be extremely slow. Every time you call Remove it has to scan through the entire list to find the element you want to remove. Every time you call RemoveAt it has to move subsequent elements 1 position to the left. As such, any solution using Remove or RemoveAt, would require quadratic time, O(n²).

    Use RemoveAll if you can. Otherwise, the following pattern will filter the list in-place in linear time, O(n).

    // Create a list to be filtered
    IList elements = new List(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
    // Filter the list
    int kept = 0;
    for (int i = 0; i < elements.Count; i++) {
        // Test whether this is an element that we want to keep.
        if (elements[i] % 3 > 0) {
            // Add it to the list of kept elements.
            elements[kept] = elements[i];
            kept++;
        }
    }
    // Unfortunately IList has no Resize method. So instead we
    // remove the last element of the list until: elements.Count == kept.
    while (kept < elements.Count) elements.RemoveAt(elements.Count-1);
    

提交回复
热议问题