【问题标题】: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) } 的作用来解释:

    1. 我们从 4(对象长度)> 0 开始。
    2. 编号 1 已生成并删除。
    3. 计数 = 1
    4. 3(对象长度)>1
    5. 编号 3 已生成并删除。
    6. 计数 = 2
    7. 2(对象的长度)不大于计数
    8. 我们已经完成了,所以我们有[2, 4]

    使用delete_if

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 2019-06-24
      • 2021-12-03
      相关资源
      最近更新 更多