Changing a list while iterating over its elements with a foreachloop

  • Thread starter Thread starter Andreas Schmitt
  • Start date Start date
A

Andreas Schmitt

I am somewhat new to C# and I ran into a problem in a small program I am
writing for teaching myself.

I am handling a list ob objects and I want to delete some of them inside
a loop like in:

foreach (Object object in objList)
{
if (object.status() == deleted)
{
objList.remove(object);
}
}

The problem here is that the list is changed while iterating over its
elements. I know one could make this work in C++ because the remove
method of the C++ STL list template returned an iterator to the next
valid object of the list. Is there any equivalent or other elegant
solution to do something like this?
I have read through all documentation I could find about the list class
in the past two days but I didn't find anything and I don't have much
literature on C# yet either.

Any help would be appreciated.
 
System.Collections.Generic.List has a RemoveAll function:

List<object> list = new List<object>();

Predicate<object> pred = delegate(object item) { return item.status ==
deleted; };
list.RemoveAll(pred);

-James
 
james said:
System.Collections.Generic.List has a RemoveAll function:

List<object> list = new List<object>();

Predicate<object> pred = delegate(object item) { return item.status ==
deleted; };
list.RemoveAll(pred);

Yes, but that only works if I just want to delete.. what if the foreach
loop contains stuff like this:

{
if (object.status() == deleted) do this

if (object.status() == something else) do this

..
..
..
}

See my problem? I kinda want to be able to do many things in one foreach
loop depending on a condition, including removing objects. I don't want
to have a seperate loop or command just to delete something from the
loop, I want to be able to do whatever is necessary depending on the
state within one single loop. Is that possible in C# with the List class?
I mean using the removeAll command as a seperate command before the
other loop is ok, but not the most elegant way to do it...
 
Hi,


The problem here is that the list is changed while iterating over its
elements. I know one could make this work in C++ because the remove method
of the C++ STL list template returned an iterator to the next valid object
of the list. Is there any equivalent or other elegant solution to do
something like this?


You will have to keep track of the instances you need to remove and remove
them later on another loop:

ArrayList toDel = new ArrayList()
foreach (Object obj in objList)
{
if (obj.status() == deleted)
{
toDel.Add( obj)
}
}

foreach( Object obj in toDel )
objList.remove(obj);
 
Hi,

Andreas Schmitt said:
james schrieb:
See my problem? I kinda want to be able to do many things in one foreach
loop depending on a condition, including removing objects. I don't want to
have a seperate loop or command just to delete something from the loop, I
want to be able to do whatever is necessary depending on the state within
one single loop. Is that possible in C# with the List class?
I mean using the removeAll command as a seperate command before the other
loop is ok, but not the most elegant way to do it...

You can modify the status of the instances. what You can not do is modify
the list
 
the foreach loop uses an iterator, so if you were to remove an item from the
list, the iterator is no longer valid. to prevent errors or
unwanted/unexpected results, you cant remove items from a list your iterating
in a foreach loop.
 
You could try doing it backwards so it's not trying to access past the end
of the list. I think I actually used this somewhere, but I can't find it
right now, so maybe I didn't; I can't remember. Here's the theory. It's
free to try!

For (i = myList.Count-1; i < 0; i--)
if (obj.Status == deleted)
obj.remove();

Robin S.
 
Andreas Schmitt said:
I am somewhat new to C# and I ran into a problem in a small program I am
writing for teaching myself.

I am handling a list ob objects and I want to delete some of them inside a
loop like in:

foreach (Object object in objList)
{
if (object.status() == deleted)
{
objList.remove(object);
}
}

The problem here is that the list is changed while iterating over its
elements. I know one could make this work in C++ because the remove method
of the C++ STL list template returned an iterator to the next valid object
of the list. Is there any equivalent or other elegant solution to do
something like this?

C++ list is like .NET LinkedList
C++ vector is like .NET List
 
Chris Dunaway said:
For (i = myList.Count-1; i < 0; i--)
if (obj.Status == deleted)
obj.remove();


I think you mean

For (i = myList.Count-1; i > 0, i--) //Note i > 0


Thank you, you're right. I was thinking "Do Until" not "Do While". It was
really late when I posted that.

Robin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top