Search code examples
c#linqlistremoveall

c# iteratively removing and adding items directly to a List?


I have searched through quite a few examples here on how to use the .remove and .removeAll extensions for a list. In trying to make this work, I seem to be having trouble getting the .removeAll to actually remove items from a List in the way that I want. What it is doing is keeping one copy of every value in the List.

The loop is iterating through a set of values described by 'k.' What I want is IF a value of 'k' is ALREADY on the List, I want to remove it completely from the List. IF a value of 'k' is encountered that is NOT on the list, I want to add it.

            for(double k=Low[0]; k<=High[0]; k +=TickSize)  
            {   
                if(LiTZ.Contains(k) )   { //if k is in list
                    LiTZ.RemoveAll(item => item == k); //remove it
                }
                else    {
                    LiTZ.Add(k);  //if k not in list, add it 
                }   
            }

I have also thought about creating a separate list, and adding to that list in the first 'if' statement, then comparing and somehow deleting items from the first list like so:

                for(double k=Low[0]; k<=High[0]; k +=TickSize)  
                {   
                    if(LiTZ.Contains(k) )   { //if k is in list
                        LiRemovalList.Add(k); //List of items to remove later
                    }
                    else    {
                        LiTZ.Add(k);  //if k not in list, add it 
                    }   
                }
               //Code to compare and remove items in LiRemovalList from LiTZ

Is it possible to iterate directly on a List in the way that I am trying without having to create other Lists?


Solution

  • It's not. You cannot change a collection while iterating it with a foreach loop or an ascendent for loop because the enumeration operation will fail after you've removed an item.

    You can remove items using a backwards for loop like so:

    for (int i = LiTZ.Count - 1; i >= 0; i--) {
      if (LiTZ[i] == something) {
         LiTZ.RemoveAt(i);
      }
    }
    

    But probably the best choice here for you would be by creating a new list.