Ruby:在迭代同一个数组时删除数组元素会发生什么?

时间:2014-01-19 06:39:05

标签: ruby arrays

我正在使用for迭代一个数组,当满足某个条件时,我需要从数组中删除当前元素。这是安全的操作吗?

for arrayElement in array1 do
    if (arrayElement < min) then
         array1.delete(arrayElement)
    end
end

或者,我应该修改我的代码以在for block之外执行删除吗?

3 个答案:

答案 0 :(得分:3)

不,这是不安全的操作,因为迭代器通常不希望收集在它们下面发生变化。根据(迭代器的)实现,您将获得两次(或更多)元素或根本不会看到某些元素。

您应该迭代(或修改)副本,而不是原始数组。

答案 1 :(得分:3)

这不安全。迭代时不要更改底层容器。这可能会导致意外行为。

例如,以下代码会导致无限循环:

a = [1]
a.each { a.push 1 }

您可以使用Array#delete_if编写代码:

array1 = [5, 4, 3, 1, 2, 7, 8]
min = 4
array1.delete_if { |arrayElement|
    arrayElement < min
}
array # => [5, 4, 7, 8]

答案 2 :(得分:1)

您的问题缺少min的内容,但您是否考虑过使用delete_if方法?

ex:array1.delete_if { |x| x < min }

来自http://www.ruby-doc.org/core-2.1.0/Array.html#method-i-delete_if

  

删除块评估为true的self的每个元素。

     

每次调用块时,数组都会立即更改,而不是在迭代结束后更改。