【问题标题】:Ruby: deleting object while looping over list with that objectRuby:在使用该对象循环列表时删除对象
【发布时间】:2017-08-05 21:24:23
【问题描述】:
所以我有多个列表来跟踪 2D 游戏中的对象,但如果这些对象离开屏幕,我想删除这些对象,以便它们不再更新。我下面的内容对我有用,但这不适用于其他语言。通常我必须创建另一个“销毁列表”来保存我想要销毁的对象,然后再次循环以删除它们,因为在迭代时无法从列表中删除对象而不会出现一些明显的故障。
是 Ruby 在执行此操作时没有显示任何明显的故障,还是 Ruby 的数组在从列表中删除多个可能的对象时工作方式不同,而它仍在迭代?
objects = []
objects.each{|o| o.withinBounds ? o.update : objects.delete(o)}
【问题讨论】:
标签:
ruby
loops
destroy
libgosu
【解决方案1】:
在 Ruby 中,如果你按照你所说的去做,你实际上会发现一个小故障。
试试这个:
objects = [1,2,3,4]
objects.each { |el| objects.delete(el) }
=> [2, 4]
您可能希望结果是一个空数组,但事实并非如此。我们弄乱了arr 的元素,each 变得混淆,因为数组的长度发生了变化。每个迭代器在伪代码中看起来像这样:
count = 0
while length(objects) > count
yield objects[count]
count + 1
end
因此,在我上面展示的示例中,我们得到[2, 4] 的原因可以通过逐步分析objects.each { |el| objects.delete(el) } 的作用来解释:
- 我们从 4(对象长度)> 0 开始。
- 编号 1 已生成并删除。
- 计数 = 1
- 3(对象长度)>1
- 编号 3 已生成并删除。
- 计数 = 2
- 2(对象的长度)不大于计数
- 我们已经完成了,所以我们有
[2, 4]
使用delete_if:
new_objects = objects.delete_if {|o| o.withinBounds }