ruby在每个循环上获得下一个值

时间:2011-10-10 01:29:48

标签: ruby each

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

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

答案是......

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

还可以获得下一个下一个值吗?

3 个答案:

答案 0 :(得分:12)

Ruby 1.8.7开始,Enumerable模块的方法each_cons几乎完全符合您的要求:

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

对于连续< n>的每个阵列迭代给定块。元素。如果没有给出阻止,则返回一个枚举器
例如: -

(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(:+)

答案 1 :(得分:7)

像这样:

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]

答案 2 :(得分:1)

一种不使用索引的方法是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