有效地从“foreach"中删除项目 [英] Efficiently deleting item from within 'foreach'

查看:27
本文介绍了有效地从“foreach"中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我能想到的最好的方法是:

For now, the best I could think of is:

bool oneMoreTime = true;
while (oneMoreTime)
{
    ItemType toDelete=null;
    oneMoreTime=false;
    foreach (ItemType item in collection)
    {
        if (ShouldBeDeleted(item))
        {
            toDelete=item;
            break;
        }
    }
    if (toDelete!=null)
    {
        collection.Remove(toDelete);
        oneMoreTime=true;
    }
}

我知道这里至少有一个额外的变量,但我包含它是为了提高算法的可读性.

I know that I have at least one extra variable here, but I included it to improve the readability of the algorithm.

推荐答案

RemoveAll"方法是最好的.

The "RemoveAll" method is best.

另一种常用技术是:

var itemsToBeDeleted = collection.Where(i=>ShouldBeDeleted(i)).ToList();
foreach(var itemToBeDeleted in itemsToBeDeleted)
    collection.Remove(itemToBeDeleted);

另一种常用技术是使用for"循环,但要确保向后:

Another common technique is to use a "for" loop, but make sure you go backwards:

for (int i = collection.Count - 1; i >= 0; --i)
    if (ShouldBeDeleted(collection[i]))
        collection.RemoveAt(i);

另一种常用技术是将删除的项目添加到新集合中:

Another common technique is to add the items that are not being removed to a new collection:

var newCollection = new List<whatever>();
foreach(var item in collection.Where(i=>!ShouldBeDeleted(i))
    newCollection.Add(item);

现在您有两个集合.如果您想以两个集合结束,我特别喜欢的一种技术是使用不可变数据结构.对于不可变的数据结构,删除"一个项目不会改变数据结构;它会给你一个新的数据结构(如果可能的话,它会重新使用旧的数据结构),它没有你删除的项目.使用不可变数据结构,您不会修改正在迭代的内容,因此没有问题:

And now you have two collections. A technique I particularly like if you want to end up with two collections is to use immutable data structures. With an immutable data structure, "removing" an item does not change the data structure; it gives you back a new data structure (that re-uses bits from the old one, if possible) that does not have the item you removed. With immutable data structures you are not modifying the thing you're iterating over, so there's no problem:

var newCollection = oldCollection;
foreach(var item in oldCollection.Where(i=>ShouldBeDeleted(i))
    newCollection = newCollection.Remove(item);

var newCollection = ImmutableCollection<whatever>.Empty;
foreach(var item in oldCollection.Where(i=>!ShouldBeDeleted(i))
    newCollection = newCollection.Add(item);

完成后,您有两个集合.新的删除了项目,旧的和以前一样.

And when you're done, you have two collections. The new one has the items removed, the old one is the same as it ever was.

这篇关于有效地从“foreach"中删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆