Ruby';s";每一个;方法不迭代数组中的所有项?

Ruby';s";每一个;方法不迭代数组中的所有项?,ruby,loops,each,Ruby,Loops,Each,我正在尝试以下代码: a = [1,2,3,4] a.each do puts "Removing #{a.last}" a.pop end 但是我没有得到所有四个数字,而是得到了前三个。实际上,执行类似puts a.length的操作会返回1,而puts ing则会显示元素“1”仍然存在 我需要如何正确使用该方法? (我使用的是Ruby 2.0)。我怀疑发生这种情况是因为您在修改列表时正在迭代列表中的元素 请尝试以下操作: a = [1,2,3,4] until a.

我正在尝试以下代码:

a = [1,2,3,4]  
a.each do  
  puts "Removing #{a.last}"  
  a.pop  
end
但是我没有得到所有四个数字,而是得到了前三个。实际上,执行类似puts a.length的操作会返回1,而puts ing则会显示元素“1”仍然存在

我需要如何正确使用该方法?
(我使用的是Ruby 2.0)。

我怀疑发生这种情况是因为您在修改列表时正在迭代列表中的元素

请尝试以下操作:

a = [1,2,3,4]
until a.empty? do
  puts "Removing #{a.last}"
  a.pop
end

看看输出,它清楚地解释了为什么在您看来,每个数组元素都没有运行。由于您是
pop
(ing),因此最后一个元素将被删除。当每个
2
传递到块时,原始数组
a
为空,因此
each
停止迭代:

a = [1,2,3,4]  
a.each do |i| 
  puts i
  puts "Removing #{a.last}"  
  p a.pop  
  p "========"
end
输出:

因此,您可以使用以下选项:

a = [1,2,3,4]  
(0...a.size).each do |i|
p a.pop
end
输出:


其他一些答案说明了代码不起作用的原因

另一种方法是这样做(前提是
a
中没有
nil
false
):

试试这个:

a.count.times do a.pop and puts "Removing #{a.last + 1 rescue 1}" end

应该在do循环中执行相同的操作

问题
当您在
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
现在a在迭代时保持不变,而改为b。 因此在这个循环的末尾,
a=[1,2,3,4]
b=[]

在你说了
a=b
之后,你会得到想要的结果


当然您可以将其调整为从后面弹出元素。只需确保在副本上工作,以便在迭代过程中不会更改元素。

您实际上想要完成什么?我想要完成的是在弹出数组时打印数组的每个元素。我试图通过电子书之类的东西自学Ruby。看来我还有很长的路要走。谢谢你的回答。就在现场。谢谢你的另一个方法。谢谢你非常有启发性的回答。很有帮助,也吸取了教训。谢谢你的回答。
a = [1,2,3,4]
while e = a.pop
  puts "Removing #{e}"
end
a.count.times do a.pop and puts "Removing #{a.last + 1 rescue 1}" end
a = [1,2,3,4]
a.each do
  |thing| 
  puts thing
  a.delete(thing)
end
 a = [1,2,3,4]
 b = a.clone
 a.each do
   |thing|
   puts thing
   b.delete(thing)
 end