现在,我能想到的最好的是:
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; } }
我知道我在这里至少有一个额外的变量,但我把它包含在内,以提高算法的可读性.
解决方法
“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; --i) 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);
要么
var newCollection = ImmutableCollection<whatever>.Empty; foreach(var item in oldCollection.Where(i=>!ShouldBeDeleted(i)) newCollection = newCollection.Add(item);
当你完成后,你有两个集合.新的项目已删除,旧的是与以前相同的.