a = ['red', 'green', 'blue', 'purple']
a.each do |e|
puts e
if e == 'green'
a.delete(e)
end
end
通过运行上面的代码,我得到以下的输出:红宝石删除数组元素,而迭代
red
green
purple
有人能向我解释发生了什么幕后?
a = ['red', 'green', 'blue', 'purple']
a.each do |e|
puts e
if e == 'green'
a.delete(e)
end
end
通过运行上面的代码,我得到以下的输出:红宝石删除数组元素,而迭代
red
green
purple
有人能向我解释发生了什么幕后?
这是的一部分。]实施each
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
所以简单地移动沿着阵列的“读头”,直到它到达终点。
当您删除"green"
时,阵列的元素将被移位以取代它的位置,并且"blue"
现在是绿色所在的位置。但是我们已经阅读了这个位置的元素。下一个要读取的元素是紫色的。
这正是为什么你不应该改变你正在迭代的集合(除非这个效果是你真正想要的)。
我无法理解的本地代码
这里是一个“读头”的心理模型的可视化一点。
v
red green blue purple # print red
# next
v
red green blue purple # print green
v
red blue purple # delete green in the same iteration
# next
v
red blue purple # print purple
甚至在模块完成执行之前就进行了转换? 其实,我不明白本机代码:( 你可以写一个伪代码吗? –
@AkashCP这个转换是在'delete'返回之前进行的,是的。 –
为了增加Sergio的解释,更惯用的方法来修改阵列将是:
a = ['red', 'green', 'blue', 'purple']
a.reject! do |e|
puts e
e == 'green'
end
这样:
2.2.5 :001 > a = ['red', 'green', 'blue', 'purple']
=> ["red", "green", "blue", "purple"]
2.2.5 :002 > a.reject! do |e|
2.2.5 :003 > puts e
2.2.5 :004?> e == 'green'
2.2.5 :005?> end
red
green
blue
purple
=> ["red", "blue", "purple"]
2.2.5 :006 >
不,你应该得到的“红,蓝,紫”。什么是你使用的Ruby版本? – Mohanraj
我正在使用ruby 2.3.3p222。无论如何,我正在删除后,所以'绿色'应该打印任何方式。我想知道'蓝'是如何跳过的? –
是的你是对的。 – Mohanraj