Ruby:在使用对象循环列表时删除对象

Ruby:在使用对象循环列表时删除对象,ruby,loops,destroy,libgosu,Ruby,Loops,Destroy,Libgosu,因此,我有多个列表来跟踪2D游戏中的对象,但如果这些对象离开屏幕,我想删除这些对象,这样它们就不再更新。下面的内容适用于我,但在其他语言中不适用。通常,我必须创建另一个“销毁列表”,保存我要销毁的对象,然后再次循环以删除它们,因为在迭代过程中无法在没有可见故障的情况下从列表中删除对象 Ruby只是在执行此操作时没有显示任何可见的故障,还是Ruby的数组在仍在迭代时从列表中删除多个可能的对象时工作方式不同 objects = [] objects.each{|o| o.withinBounds

因此,我有多个列表来跟踪2D游戏中的对象,但如果这些对象离开屏幕,我想删除这些对象,这样它们就不再更新。下面的内容适用于我,但在其他语言中不适用。通常,我必须创建另一个“销毁列表”,保存我要销毁的对象,然后再次循环以删除它们,因为在迭代过程中无法在没有可见故障的情况下从列表中删除对象

Ruby只是在执行此操作时没有显示任何可见的故障,还是Ruby的数组在仍在迭代时从列表中删除多个可能的对象时工作方式不同

objects = []

objects.each{|o| o.withinBounds ? o.update : objects.delete(o)}

在Ruby中,如果你按照你说的去做,你会发现一个小故障

试试这个:

objects = [1,2,3,4]
objects.each { |el| objects.delete(el) }
=> [2, 4]
您可能希望结果为空数组,但实际并非如此。我们正在弄乱
arr
的元素,并且
每个
都会混淆,因为数组的长度已更改。在伪代码中,每个迭代器看起来像这样:

count = 0
while length(objects) > count
  yield objects[count]
  count + 1
end
因此,在我上面展示的示例中,我们获得
[2,4]
的原因可以通过对
对象的逐步分析来解释。每个{el | objects.delete(el)}
都在做:

  • 我们从4(对象长度)>0开始
  • 编号1已生成,并已删除
  • 计数=1
  • 3(物体长度)>1
  • 编号3已生成并删除
  • 计数=2
  • 2(对象长度)不大于计数
  • 我们完成了,所以我们有
    [2,4]
  • 有一种更好的方法可以完成您正在尝试的工作,方法是:

    new_objects = objects.delete_if {|o| o.withinBounds }