【发布时间】:2014-09-08 13:49:43
【问题描述】:
我正在尝试找到一种优雅的方式来遍历列表,同时删除项目。
I know this solution。但我的条件更难:
- 全部单线程在这里
- 迭代必须向前。
- 每个项目都必须只处理一次。
- 多个和随机项目可以在处理 1 个项目时移除。
- 项目是复杂而智能的对象。他们执行一个自定义方法,它可以决定删除一些项目(从 0 到全部)。
- (添加和插入也可以发生,但现在这并不重要,如果有办法同时处理,那就太好了)
问题:这可能吗?如果是,如何?
我有将对象标记为已移除/非活动的想法。当我稍后再次迭代时,我将删除它们而不调用它们做事。迭代会经常重复,这就是为什么每个对象在每次迭代中都必须恰好有 1 圈。那行得通吗?
这就是我现在处理事情的方式。它并不完美,但会给你我希望的提示。
伪代码:
class Foo
{
public void DoStuff()
{
// do other stuff
if (condition)
Kill(x); // should result in list.RemoveAt(x) somehow
}
}
class Program
{
[STAThread]
static void Main(string[] args)
{
List<Foo> list = new List<Foo>();
for (int i = 0; i < 15; i++)
list.Add(new Foo());
for (int i = 0; i < list.Count; i++)
list[i].DoStuff();
Console.ReadKey();
}
}
(这不是 XY 问题。我敢肯定。多年来我一直在想这个问题,我决定最终找到一个可靠的解决方案。我正在使用 C# 来解决这个问题。这不是恶作剧. 如果它看起来像它,我很抱歉。)
感谢您的帮助!
【问题讨论】:
-
这听起来像是在说疯话,究竟是什么在处理它们时删除它们?在不同的线程上运行的东西?
-
所以它是删除可能导致在其他位置修改列表的项目的行为吗?还是问题从其他线程访问列表?
-
这是真的还是只是个谜?其中一些限制很奇怪。
-
为了能够回答问题,您需要提供更多有关应用程序所需行为的信息。例如,如果您正在迭代列表,并且您在第二个元素上调用某个方法,该方法从列表中删除元素 1 和 3,您是否希望元素 3 仍然被访问,即使它已被删除?是否存在限制您创建列表副本的限制?它们是真正的限制,还是只是一个思想问题?
-
@Alex 想象一下
foreach循环体中的代码从它正在迭代的集合中删除项目。只涉及一个线程,但从迭代器的角度来看,它在尝试迭代集合时从“其他地方”发生了变异。这很容易创建:foreach(var item in list) list.RemoveAt(random.Next(list.Count));