Tsvi Tannin
Tsvi Tannin

Reputation: 407

Iterate every two elements in ruby for loop

How do you create a for loop like

for (int x=0; x<data.length; x+=2) 

in ruby? I want to iterate through an array but have my counter increment by two instead of one.

Upvotes: 17

Views: 19375

Answers (4)

Tsvi Tannin
Tsvi Tannin

Reputation: 407

(0..data.length).step(2) do |x|
puts x
end

This seems like the closest substitute.

Upvotes: 2

the Tin Man
the Tin Man

Reputation: 160551

Ruby's step is your friend:

0.step(data.length, 2).to_a
=> [0, 2, 4, 6]

I'm using to_a to show what values this would return. In real life step is an enumerator, so we'd use it like:

data = [0, 1, 2, 3, 4, 5]
0.step(data.length, 2).each do |i|
  puts data[i]
end

Which outputs:

0
2
4
   <== a nil 

Notice that data contains six elements, so data.length returns 6, but an array is a zero-offset, so the last element would be element #5. We only get three values, plus a nil which would display as an empty line when printed, which would be element #6:

data[6]
=> nil

That's why we don't usually walk arrays and container using outside iterators in Ruby; It's too easy to fall off the end. Instead, use each and similar constructs, which always do the right thing.

To continue to use step and deal with the zero-offset for arrays and containers, you could use:

0.step(data.length - 1, 2)

but I'd still try working with each and other array iterators as a first choice, which @SergioTulentsev was giving as an example.

Upvotes: 8

Abe Voelker
Abe Voelker

Reputation: 31574

Using Range#step:

a = (1..50).to_a
(1..a.size).step(2).map{|i| a[i-1]} # [1, 3, 5, 7, 9 ...

Upvotes: 0

John Ledbetter
John Ledbetter

Reputation: 14173

If what you really want is to consume 2 items from an array at a time, check out each_slice.

[1,2,3,4,5,6,7,8,9].each_slice(2) do |a, b|
  puts "#{a}, #{b}"
end

# result
1, 2
3, 4
5, 6
7, 8
9,

Upvotes: 45

Related Questions