开发者

How can I do this special foreach iterator? [duplicate]

开发者 https://www.devze.com 2023-01-30 03:41 出处:网络
This question already has answers here: Closed 12 years ago. Possible Duplicate: How to modify or delete items from an enumerable collection while iterating through it in C#
This question already has answers here: Closed 12 years ago.

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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消