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

前端 未结 27 2291
忘了有多久
忘了有多久 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条回答
  • 2020-11-21 23:21

    Trace the elements to be removed with a property, and remove them all after process.

    using System.Linq;
    
    List<MyProperty> _Group = new List<MyProperty>();
    // ... add elements
    
    bool cond = true;
    foreach (MyProperty currObj in _Group)
    {
        if (cond) 
        {
            // SET - element can be deleted
            currObj.REMOVE_ME = true;
        }
    }
    // RESET
    _Group.RemoveAll(r => r.REMOVE_ME);
    
    0 讨论(0)
  • 2020-11-21 23:22

    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));
    
    0 讨论(0)
  • 2020-11-21 23:23

    Using .ToList() will make a copy of your list, as explained in this question: ToList()-- Does it Create a New List?

    By using ToList(), you can remove from your original list, because you're actually iterating over a copy.

    foreach (var item in listTracked.ToList()) {    
    
            if (DetermineIfRequiresRemoval(item)) {
                listTracked.Remove(item)
            }
    
         }
    
    0 讨论(0)
  • 2020-11-21 23:23

    By assuming that predicate is a Boolean property of an element, that if it is true, then the element should be removed:

            int i = 0;
            while (i < list.Count())
            {
                if (list[i].predicate == true)
                {
                    list.RemoveAt(i);
                    continue;
                }
                i++;
            }
    
    0 讨论(0)
  • 2020-11-21 23:24

    Reverse iteration should be the first thing to come to mind when you want to remove elements from a Collection while iterating over it.

    Luckily, there is a more elegant solution than writing a for loop which involves needless typing and can be error prone.

    ICollection<int> test = new List<int>(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
    
    foreach (int myInt in test.Reverse<int>())
    {
        if (myInt % 2 == 0)
        {
            test.Remove(myInt);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 23:25

    I would reassign the list from a LINQ query that filtered out the elements you didn't want to keep.

    list = list.Where(item => ...).ToList();
    

    Unless the list is very large there should be no significant performance problems in doing this.

    0 讨论(0)
提交回复
热议问题