Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to modify a List while iterating through it?

Tags:

c#

.net

I have the following:

foreach (var depthCard in depthCards)
{
    var card = InternalGetCard(db, depthCard.CardId);
    var set = InternalGetSet(db, (int)card.ParentSetId);
    var depthArray = InternalGetDepthArrayForCard(db, set.SetId);
    foreach (var cardToUpdate in set.Cards)
    {
        // do stuff
        SaveChanges(db);
        // since I already took care of it here, remove from depthCards
        depthCards.Remove(depthCardToUpdate);
    }
}

This isn't working though because I'm modifying the collection in the middle of a loop. Is there some type of collection that does allow this type of access?

I don't want to ToList() the depthCards because I already have them and I want to modify that list as I'm iterating. Is this possible?

like image 314
RobVious Avatar asked Jul 20 '13 22:07

RobVious


People also ask

Can we modify list while iterating Java?

Even though java. util. ArrayList provides the remove() methods, like remove (int index) and remove (Object element), you cannot use them to remove items while iterating over ArrayList in Java because they will throw ConcurrentModificationException if called during iteration.

Can we modify list while iterating C#?

No, ToList creates a new list.

What happens if you modify the value of an element in a list while iterating using iterators?

The size of the List is not being changed, but the object at the index is changing, so technically the List is being modified.

Can we add element in list while iterating?

You can't modify a Collection while iterating over it using an Iterator , except for Iterator. remove() . This will work except when the list starts iteration empty, in which case there will be no previous element. If that's a problem, you'll have to maintain a flag of some sort to indicate this edge case.


3 Answers

It's possible, the trick is to iterate backwards:

for (int i = depthCards.Count - 1; i >= 0; i--) {
  if (depthCards[i] == something) { // condition to remove element, if applicable
     depthCards.RemoveAt(i);
  }
}
like image 169
Óscar López Avatar answered Oct 01 '22 03:10

Óscar López


You can iterate backwards with a for-loop

for (int i = depthCards.Count - 1; i >= 0; i--)
{
    depthCards.RemoveAt(i);
}

or if you just want to remove items on a condition, use List.RemoveAll:

depthCardToUpdate.RemoveAll(dc => conditionHere);
like image 23
Tim Schmelter Avatar answered Oct 01 '22 03:10

Tim Schmelter


You can create a custom enumerator that handles this for you. I did this once and it was a bit tricky but worked after some finesse.

See: http://www.codeproject.com/Articles/28963/Custom-Enumerators

like image 24
Haney Avatar answered Oct 01 '22 05:10

Haney