【发布时间】:2011-01-17 22:47:01
【问题描述】:
我经常需要这样的东西:
foreach (Line line in lines)
{
if (line.FullfilsCertainConditions())
{
lines.Remove(line)
}
}
这不起作用,因为我总是得到InvalidOperationException,因为枚举器在循环期间发生了变化。
因此,我将所有此类循环更改为以下内容:
List<Line> remove = new List<Line>();
foreach (Line line in lines)
{
if (line.FullfilsCertainConditions())
{
remove.Add(line)
}
}
foreach (Line line in remove) {
{
lines.Remove(line);
}
我不确定这是否真的是最好的方法,因为在最坏的情况下,我必须在原始列表上迭代 2 次,因此它需要时间 2n 而不是 n。
有没有更好的方法来做到这一点?
编辑:
我可以使用 Mark 的回答来做到这一点!但是如果我的集合没有实现 RemoveAll() 怎么办?
例如一个
System.Windows.Controls.UIElementCollection
编辑 2:
再次在 Mark 的帮助下,我现在可以进行以下调用以删除所有 ScatterViewItems:
CollectionUtils.RemoveAll(manager.getWindow().IconDisplay.Items, elem => elem.GetType() == typeof(ScatterViewItem));
【问题讨论】:
-
我前段时间遇到了同样的问题,但没有解决方案。更糟糕的是 - 它不是 2n 而是 n^2,因为
lines.Remove(line)再次遍历集合。 -
但是 O(2n) 确实等于 O(n) :-):在 Java 中,您可以使用 Iterator 来执行此操作,或者使用 Copy-on-Write Collection 实现,它允许在迭代时进行修改.
-
@Marc Gravell 非常感谢!不幸的是,我无法再次投票!