4

Say you have this array:

arr = w|one two three|

How can I iterate over it by having two consecutive elements as block arguments like this:

1st cycle: |nil, 'one'|
2nd cycle: |'one', 'two'|
3rd cycle: |'two', 'three'|

Sofar I came only with this:

arr.each_index { |i| [i - 1 < 0 ? nil: arr[i - 1], arr[i]] }

Any better solutions? Is there something like each(n)?

Alexander Popov
  • 23,073
  • 19
  • 91
  • 130

2 Answers2

9

You can add nil as the first element of your arr and use Enumerable#each_cons method:

arr.unshift(nil).each_cons(2).map { |first, second| [first, second] }
# => [[nil, "one"], ["one", "two"], ["two", "three"]]

(I'm using map here to show what exactly is returned on each iteration)

Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
5
> [1, 2, 3, 4, 5, 6, 7, 8, 9].each_cons(2).to_a
# => [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]
Hetal Khunti
  • 787
  • 1
  • 9
  • 23