从'foreach'中有效删除项目

Dan*_*dor 14 .net c# collections

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ert 35

"RemoveAll"方法是最好的.

另一种常见技术是:

var itemsToBeDeleted = collection.Where(i=>ShouldBeDeleted(i)).ToList();
foreach(var itemToBeDeleted in itemsToBeDeleted)
    collection.Remove(itemToBeDeleted);
Run Code Online (Sandbox Code Playgroud)

另一种常见的技术是使用"for"循环,但要确保你倒退:

for (int i = collection.Count - 1; i >= 0; --i)
    if (ShouldBeDeleted(collection[i]))
        collection.RemoveAt(i);
Run Code Online (Sandbox Code Playgroud)

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

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

现在你有两个系列.如果你想最终得到两个集合,我特别喜欢的一种技术是使用不可变数据结构.使用不可变数据结构,"删除"项不会改变数据结构; 它会返回一个新的数据结构(如果可能的话,重新使用旧的数据结构),它没有你删除的项目.使用不可变数据结构,你不会修改你正在迭代的东西,所以没有问题:

var newCollection = oldCollection;
foreach(var item in oldCollection.Where(i=>ShouldBeDeleted(i))
    newCollection = newCollection.Remove(item);
Run Code Online (Sandbox Code Playgroud)

要么

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

当你完成后,你有两个收藏.新的项目已删除,旧的项目与以往相同.

  • @BKSpurgeon:肯定是!所有比删除的元素“高”的元素都需要向下移动一位。如果您需要有效地执行此操作,则*不要使用列表*。使用无序类型(例如哈希集),或使用有效支持此操作的有序类型,例如双向链接列表,可连接的双端队列,等等。 (2认同)

Dan*_*dor 14

就在我完成打字时,我记得有一种lambda方式可以做到这一点.

collection.RemoveAll(i=>ShouldBeDeleted(i));
Run Code Online (Sandbox Code Playgroud)

更好的方法?

  • 只是一个FYI:这可以转换为方法组.collection.RemoveAll(ShouldBeDeleted). (2认同)