【问题标题】:How does modifying an array while iterating work in Ruby?在 Ruby 中如何在迭代时修改数组?
【发布时间】:2020-05-29 18:30:14
【问题描述】:

在 Ruby 中给定一个数组:

numbers = [1, 2, 3, 4]

我对在迭代数组时修改数组时发生的结果感到困惑:

numbers.each do |number|
  p number
  numbers.shift(1)
end

我在运行代码时得到的输出是 1 和 3。1 对于第一个循环非常有意义,但我似乎无法弄清楚为什么程序返回 3。

我修改了原始代码,以便我可以看到沿途每一步发生的情况,并包含井号“----”以了解每个循环何时完成运行:

numbers = [1, 2, 3, 4]
numbers.each_with_index do |number, index|
  p "Array is #{numbers} and index is #{index}"
  p "Number is #{number}"
  numbers.shift(1)
  p "The Array after shift is now #{numbers}, number is #{number}, and the index is now #{index}"
  p "----"
end

通过第一个循环,shift成功从原始数组中移除1,数组变为[2,3,4],而“number”为1。但是在第二个循环中,而不是“number”返回2它返回 3。

我认为唯一有意义的方法是索引本身是否必须确定要从数组中删除的项目。当索引为 0 时,它从数组中删除索引 0 处的数组项,当索引为 1 时,它从更新后的数组中删除索引 1 处的数组项。然后当索引为 2 时循环停止,因为数组在索引 2 处不再有项目。

这是作为启动学校课程的一部分的问题。我无法弄清楚为什么代码会返回它的功能。我还尝试在调用 numbers.shift(1) 之前和之后插入 binding.pry,但它似乎没有向我澄清任何事情。

【问题讨论】:

  • 提示:试试unshift(1)numbers.reverse!
  • 试试这个:numbers.each do |number|; puts "number=#{number}, numbers=#{numbers}"; puts "numbers.shift returns #{numbers.shift(1)}"; puts "numbers after shift=#{numbers}"; end。这将显示以下内容:number=1, numbers=[1, 2, 3, 4]; numbers.shift returns [1]; numbers after shift=[2, 3, 4]; number=3, numbers=[2, 3, 4]; numbers.shift returns [2]; numbers after shift=[3, 4] 并返回 [3, 4]。然后numbers #=> [3, 4]。注意Array#each返回它的接收者,数组numbers

标签: arrays ruby


【解决方案1】:

不要将其视为值,而应将其视为地址。
枚举器(或迭代器)跟随当前地址指向的下一个地址。

1st loop:
  1. number points to the first address (with value 1)
  2. shifting array making the current 2nd address the 1st, therefore the value 2 is now on the 1st address.

2nd loop:
  1. number points to the 2nd address (with value 3)
  2. shifting array making the current 2nd address the 1st

3rd loop:
  ※same logic until 'StopIteration' is met

关于'shift',它只会删除第一个项目而不用想太多。

参考:https://apidock.com/ruby/Enumerator/next_values

【讨论】:

    【解决方案2】:
    numbers = [1, 2, 3, 4]
    

    好的,我们开始吧

    numbers.each do |number|
      # do stuff
    end
    

    第一个数字

    p number # 1, we are on the first element of [1, 2, 3, 4]
    numbers.shift(1) # numbers is now [2, 3, 4]
    

    第二个数字

    p number # 3, we are on the second element of [2, 3, 4]
    numbers.shift(1) # numbers is now [3, 4]
    

    第三个数字 - 等等,[3, 4] 没有第三个元素,我们完成了。

    【讨论】:

    • 啊,有道理!谢谢!
    猜你喜欢
    • 2010-12-18
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2017-09-25
    • 2013-01-15
    • 2016-05-16
    • 2023-01-31
    相关资源
    最近更新 更多