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

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

问题描述

现在,我能想到的最好的是:

  bool oneMoreTime = true; 
while(oneMoreTime)
{
ItemType toDelete = null;
oneMoreTime = false;
foreach(集合中的ItemType项)
{
if(ShouldBeDeleted(item))
{
toDelete = item;
break;
}
}
if(toDelete!= null)
{
collection.Remove(toDelete);
oneMoreTime = true;
}
}



我知道我至少有一个额外的变量,但是我把它包含在内,以提高算法的可读性。

解决方案

RemoveAll

另一种常见的方法是:

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

另一种常见的技术是使用for循环,但确保您向后:

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

另一种常见的技术是将 新集合:

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

现在你有两个集合,一个我特别喜欢的技术是使用不可变的数据结构,使用不可变的数据结构,一个项目不改变数据结构;它给你一个新的数据结构(如果可能的话,重新使用旧的数据结构)没有你删除的项目不可变的数据结构你不修改的东西因此没有问题:

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


$ b b

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

完成后,您有两个集合。新的项目已移除项目,旧项目与以往相同。


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.

解决方案

The "RemoveAll" method is best.

Another common technique is:

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

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

or

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天全站免登陆