tags:

views:

243

answers:

5

I have a list of rows from a dataset that I need to iterate through.

The problem is that the processing in the iteration may delete one or more rows from the list.

Since the list is being modified, I can't use a foreach() loop.

But since it is possible some of the deletions may occur at elements BEFORE the one I'm processing, I also can't use a for() loop (i.e, if I'm processing element , and that results in the deletion of element and also other elements , I can't think of a way to adjust i to correctly point to the element following the one that I was processing).

How would you tackle this problem? My current thought it is to always process the first element in the list. If it gets deleted, process the new first element. If it doesn't get deleted, the move it to an "alreadyProcessed" list, and process the new first element.

Is there an easier way?

+5  A: 

Typically this is done with a reverse loop:

List<string> Items = ...
for(int i = Items.Count - 1; i >= 0; i--)
{
   if(Items[i] == "DELETE ME")
   {
      Items.RemoveAt(i);
   }
}

This causes the items to be processed in reverse order, so if you delete an item, it does not affect the position of any items still to be processed.

David
This won't work in the case I'm considering because the deletions may occur not only at element i, but at other element(s) i+/-n, which means that i-- may or may not be pointing at the correct next element. Also, deleting more than one element could potentially leave i, or even i--, pointing at a no-longer-existing object beyond the end of the list. (Note also that I don't necessarily know how many elements might have been deleted.)
Dave Hanna
A: 
for(int i = list.Length -1, i >= 0; i--)
{
   // process and delete if you want
}
ArsenMkrt
Please declare `i`
Dario
See my comment to David above.
Dave Hanna
+1  A: 

When modifying a list I'm iterating through, I always find it easiest to build a new list with the items I want to keep, and then use the new list to do whatever it was I was going to do.

It really depends on what you're doing with the data when you're done, I suppose.

Dave
That's the direction I'm leaning toward. Thanks for the confirmation.
Dave Hanna
A: 


int i = 0;
while (i < dataSet.Tables[0].Rows.Count) {
    if (some_condition) {
       dataSet.Tables[0].Rows.RemoveAt(i);
       continue;
    }
    i++;
}
Tadas
If more than one deletion occurs (a condition I can't easily know), then i (or i++) will not be pointing at the correct next element. (The reason more than one deletion may occur is because of cascading deletes in a one-to-many relation.)
Dave Hanna
Yes, if you delete (not remove) a row. But my example removes rows from DataTable. If you use Delete() you can check RowState == RowState.Deleted of each row in your loop.
Tadas
A: 

If you can get your data into a linked list, you're golden.

lidgren