为什么''each'迭代器不能遍历整个数组?

时间:2017-03-02 10:20:01

标签: ruby each

我尝试在Ruby中执行此代码:

array=[1,2,3,4,5]
array.each do |x|
  puts array.length
  puts "Downloading #{array.length} files"
  array.pop
end

我得到了:

5
Downloading 5 files
4
Downloading 4 files
3
Downloading 3 files

我不明白为什么我只进行了三次迭代。我做错了什么(除了不使用while循环)?

3 个答案:

答案 0 :(得分:1)

之前发生的事情是:

  1. array.length是5
  2. x = 1正在处理
  3. array.shift(array.length是4)
  4. 数组长度= 4
  5. x = 2正在处理
  6. array.shift(array.length是3)
  7. x = 3正在处理
  8. array.shift(array.length是2)
  9. 现在没有更多的数组项可以迭代,因为最后3个项目(3,4,5)被弹出。

    更好的方法是反转数组并将其移位

    array=[1,2,3,4,5]
    
    array.reverse.each do |x|
      puts array.length
      puts "Downloading #{array.length} files"
      array.shift
    end
    

    现在发生的事情是,数组现在是[5,4,3,2,1]。 每个循环处理数组中的第一个项目,放置数组长度,然后使用shift删除该值。

答案 1 :(得分:0)

因为你从array开始迭代,这意味着:

1 step: puts array[0] and you delete array[4] element(array => [1, 2, 3, 4])
2 step: puts array[1] and delete array[3] element(array => [1, 2, 3])

如果要在返回后删除每个元素,可以使用多种变体进行删除,其中包括:

array.reverse.each do |x|
  puts "Downloading #{x} files"
  array.pop
end

array.size.times do
  puts "Downloading #{array.pop} files"
end

如果您不希望在此次迭代后变为空array,则可以:

array.reverse.each do |x|
  puts "Downloading #{x} files"
end

答案 2 :(得分:0)

在您的函数中,array.pop正在减少数组的长度。在最后一行

3
Downloading 3 files

您的数组长度为3,而每个循环已经运行3次。这就是为什么它不迭代下一个元素的原因。 (这里,每个循环只迭代3个元素,因为你的数组的长度是3)