当我删除“green”时,为什么Array#delete跳过“blue”并打印“green”?

时间:2014-09-22 18:59:01

标签: ruby arrays iterator

array=['red', 'green', 'blue', 'purple']
array.each do | color |
  puts(color)
  if color == 'green'
    array.delete(color)
  end
end

这会打印红色,绿色,紫色。我得知它以某种方式array.delete弄乱了迭代,但我的问题是为什么以及如何?引擎盖后面发生了什么?如果我替换array.delete(color),比如array<< ' white',然后将打印所有颜色,因此只有在从数组中删除项目时才会出现此行为。

2 个答案:

答案 0 :(得分:1)

在原始array中,green位于1索引中。因此,在第二次迭代中,当您的if表达式评估为true时,您将从原始green中删除实际条目array。因此blue进入索引1。这就是为什么在第三次迭代中,3 rd元素是purple,这就是你从预期输出中遗漏"blue"的原因。

您可以按以下方式调试它: -

array=['red', 'green', 'blue', 'purple']
array.each do | color |
  if color == 'green'
    array.delete(color)
  end
  # printing array to debug the actual array content after each iteration
  p array
end
# >> ["red", "green", "blue", "purple"]
# >> ["red", "blue", "purple"]
# >> ["red", "blue", "purple"]

答案 1 :(得分:0)

在迭代之前改变数组并在循环中动态更改索引。例如:

array = %w[red green blue purple]
array.delete 'green'
array.each { |color| puts color }

这正确地产生:

$ ruby colors.rb 
red
blue
purple