Salomanuel - 1 year ago 74
Ruby Question

# keep iterating over and over OVER an array

I realize my communicating skills are not that brilliant (I'm having issues even trying to look up for that), so I let the code speak:

``````easy_as_123 = ("a".."c").to_a
10.times do |j|
if j >= easy_as_123.length
puts "j is #{j}, letter is #{easy_as_123[j % easy_as_123.length]}"
else
puts "j is #{j}, letter is #{easy_as_123[j]}"
end
end
``````

is there a more elegant and concise solution to keep iterating over and over my [a,b,c] array?

edit, that code I posted works, that's exactly the result I'm looking for, but it's not concise nor good looking, are there methods capable of achieving in more elegant ways that same result?

`Enumerable#cycle` is your friend here. Infinite loop:

``````(?a..?c).cycle.with_index do |letter, j|
puts "j is #{j}, letter is #{letter}"
end
``````

to break a loop after 10 iterations:

``````(?a..?c).cycle.with_index do |letter, j|
break if j >= 10
puts "j is #{j}, letter is #{letter}"
end
``````

using `#take` (credits to @Stefan):

``````(?a..?c).cycle.take(10).each.with_index do |letter, j|
puts "j is #{j}, letter is #{letter}"
end
``````

other way round:

``````enum = (?a..?c).cycle
10.times do |j|
puts "j is #{j}, letter is #{enum.next}"
end
``````

without `#cycle`:

``````enum = (?a..?c).to_a
10.times do |j|
puts "j is #{j}, letter is #{enum[j % enum.length]}"
end
``````

• `if` is redundant;
• `to_a` is redundant, ranges might be enumerated.