How can I do this special foreach iterator? [duplicate]
Possible Duplicate:
How to modify or delete items from an enumerable collection while iterating through it in C#
Listen, I do not want to k开发者_C百科now about the basic foreach. I am talking about that one which control this error:
"The enumerator is not valid because the collection changed."
Which occur when I do this:
foreach(Image image in images)
{
if(...)
{
images.remove(image)
}
}
I believe there is an special iterator which handle this well, as Java has. So, how can I do this in C# please? Thank you!
Or just remove it without manually iterating at all:
images.RemoveAll(image=>...)
Works on List<T>
but many other containers don't support it.
An O(n) solution working on IList<T>
:
void RemoveWhere(this IList<T> list,Predicate<T> pred)
{
int targetIndex=0;
for(int srcIndex=0;srcIndex<list.Count;srcIndex++)
{
if(pred(list[srcIndex]))
{
list[targetIndex]=list[srcIndex];
targetIndex++;
}
for(int i=list.Count-1;i>=targetIndex;i--)
list.RemoveAt(i);
}
}
Can be sped up a bit by not assigning until you hit the first removed item.
for (var i = 0; i < images.Count; ++i)
{
if (...)
{
images.RemoveAt(i);
--i;
}
}
You can't do it in C#.
What you can do is collect the objects you want to remove, then remove them:
Image[] imagesToRemove = images.Where(image => ...).ToArray();
foreach (Image image in imagesToRemove)
images.remove(image);
Kent's answer will work given something that implements IList<T>
. For something that doesn't you will have to build up a list of the things you want to remove. For example:
public static void RemoveWhere<T>(this ICollection<T> self, Func<T, bool> predicate)
{
var toRemove = self.Where(predicate).ToList();
foreach (var i in toRemove)
self.Remove(i);
}
精彩评论