Basically, I would like to remove an item from a list whilst inside the foreach loop. I know that this is possible when using a for loop, but for other purposes, I would like to know if this is achievable using a foreach loop.
In python we can achieve this by doing the following:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in a:
print i
if i == 1:
a.pop(1)
This gives the following Output
>>>1
3
4
5
6
7
8
9
But when doing something similar in c#, I get an InvalidOperationException, I was wondering if there was a way of getting around this, without just simply using a for loop.
The code in c# that I used when the exception was thrown:
static void Main(string[] args)
{
List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9"});
foreach (string Item in MyList)
{
if (MyList.IndexOf(Item) == 0)
{
MyList.RemoveAt(1);
}
Console.WriteLine(Item);
}
}
Thanks in advance
Modify a C# collection with foreach by using a second collection. Since we cannot change a collection directly with foreach , an alternative is to use a second collection. To that second collection we then add new elements. This way we can still benefit from the simplicity that foreach offers.
The value being iterated cannot be changed, because the foreach loop relies on the IEnumerator interface, and this interface has no method to change the value being enumerated.
Collections support foreach statement using Enumarator. Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.
forEach() does not mutate the array on which it is called.
You can't do this. From the docs for IEnumerator<T>
:
An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.
Alternatives are:
The last of these alternatives is the LINQ-like solution, where you'd typically write:
var newList = oldList.Where(x => ShouldBeRetained(x)).ToList();
(Where ShouldBeRetained
is whatever logic you want, of course.) The call to ToList()
is only necessary if you actually want it in a list. This leads to more declarative code which is often easier to read. I can't easily guess what your original loop is meant to do (it seems pretty odd at the moment) whereas if you can express the logic purely in terms of the item, it can be a lot clearer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With