我正在尝试以下代码:
a = [1,2,3,4]
a.each do
puts "Removing #{a.last}"
a.pop
end
但是没有弹出所有四个数字,我只得到第一个3.确实,做一些像放置a.length的东西返回1并且放置它显示元素“1”仍然存在。
我如何正确使用该方法? (我使用的是Ruby 2.0)。
答案 0 :(得分:6)
我怀疑这种情况正在发生,因为你在修改列表的同时迭代列表中的元素。
尝试以下方法:
a = [1,2,3,4]
until a.empty? do
puts "Removing #{a.last}"
a.pop
end
答案 1 :(得分:3)
<强>问题强>
在迭代a
时,你正在改变它。
问题解释
这意味着一旦删除了一个元素,每个方法都会被抛弃,因为突然元素a
包含的数量会少一个。因此索引也被抛弃了
如果我执行此操作:
a = [1,2,3,4]
a.each do
|thing|
puts thing
a.delete(thing)
end
我将获得输出[1,3]。
那是因为发生了以下情况:
在从索引0的列表中删除1之前,2在索引1处。
删除1之后,2处于索引0而不是1,因此2不是迭代的下一个元素,而是3!
顺便说一下你可以像我用thing
那样定义一个本地块变量来访问你迭代的每个元素。
<强>解决方案强>
为了得到你想要的东西,你需要创建一个副本并进行处理。
a = [1,2,3,4]
b = a.clone
a.each do
|thing|
puts thing
b.delete(thing)
end
现在,当你迭代它并改变b时,它仍然是相同的。
因此,在此循环结束时a = [1,2,3,4]
和b =[]
在您说a = b
之后,您将获得所需的结果。
当然您可以根据背面的弹出元素进行调整。只需确保处理副本,这样就不会在迭代时更改元素。
答案 2 :(得分:2)
其他一些答案说明了为什么你的代码不起作用。
另一种方法是这样做(假设nil
中没有false
或a
):
a = [1,2,3,4]
while e = a.pop
puts "Removing #{e}"
end
答案 3 :(得分:1)
查看输出,这清楚地表明为什么你们每个人都没有运行所有的数组元素。由于你是pop
(ing)Array#pop
,所以删除了最后一个元素。当每个传递2
到块时,原始数组a
变为空,因此each
停止迭代。:
a = [1,2,3,4]
a.each do |i|
puts i
puts "Removing #{a.last}"
p a.pop
p "========"
end
的输出:强> 的
1
Removing 4
4
"========"
2
Removing 3
3
"========"
所以你可以使用下面的内容:
a = [1,2,3,4]
(0...a.size).each do |i|
p a.pop
end
的输出:强> 的
4
3
2
1
答案 4 :(得分:0)
a = [1,2,3,4]
a.length.times do
puts "Removing #{a.last}"
a.pop
end
答案 5 :(得分:0)
试试这个:
a.count.times do a.pop and puts "Removing #{a.last + 1 rescue 1}" end
在do循环中应该这样做