【问题标题】:ruby get next value on each loopruby 在每个循环中获取下一个值
【发布时间】:2011-12-04 04:44:57
【问题描述】:

我可以在每个循环中获取下一个值吗?

(1..5).each do |i|
    @store = i + (next value of i)
end

答案在哪里..

1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 = 29

我还能得到下一个值的下一个吗?

【问题讨论】:

    标签: ruby each


    【解决方案1】:

    早在Ruby 1.8.7,Enumerable 模块就有一个方法each_cons,几乎可以满足您的要求:

    each_cons(n) { ... } → 无
    each_cons(n) → an_enumerator

    为每个连续 元素数组迭代给定块。如果没有给出块,则返回一个枚举器。

    例如:

    (1..10).each_cons(3) { |a| p a }
    # outputs below
    [1, 2, 3]
    [2, 3, 4]
    [3, 4, 5]
    [4, 5, 6]
    [5, 6, 7]
    [6, 7, 8]
    [7, 8, 9]
    [8, 9, 10]
    

    唯一的问题是它不会重复最后一个元素。但这很容易解决。具体来说,你想要

    store = 0
    range = 1..5
    
    range.each_cons(2) do |i, next_value_of_i|
        store += i + next_value_of_i
    end
    store += range.end
    
    p store # => 29
    

    但你也可以这样做:

    range = 1..5
    
    result = range.each_cons(2).reduce(:+).reduce(:+) + range.end
    
    p result # => 29
    

    或者,您可能会发现以下内容更具可读性:

    result = range.end + range.each_cons(2)
                              .reduce(:+)
                              .reduce(:+)
    

    【讨论】:

      【解决方案2】:

      一种不使用索引的方法是 Enumerable#zip:

      range = 11..15
      store = 0 # This is horrible imperative programming
      range.zip(range.to_a[1..-1], range.to_a[2..-1]) do |x, y, z|
        # nil.to_i equals 0
        store += [x, y, z].map(&:to_i).inject(:+)
      end
      store
      

      【讨论】:

        【解决方案3】:

        像这样:

        range = 1..5
        store = 0
        
        range.each_with_index do |value, i|
          next_value = range.to_a[i+1].nil? ? 0 : range.to_a[i+1]
          store += value + next_value
        end    
        
        p store # => 29
        

        可能有更好的方法,但这是可行的。

        你可以像这样得到下一个值的下一个:

        range.to_a[i+2]
        

        【讨论】:

        • 如果范围被更改,此代码将中断,例如更改为11..15:它应该给出 119 时给出 65。
        • 不错!感谢您的快速回复!再想一想,@AndrewGrimm 是对的。
        • @jovhenni19,我更新了我的答案,因此它也适用于 AndrewGrimm 的示例。
        • 感谢您发现我的错误 :-)
        猜你喜欢
        • 1970-01-01
        • 2011-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多