arraysrubyfor-loopeachcurly-braces

Ruby way instead of for loop in specific case of array iteration


Coming from other languages where for loop is predominant way of iterating, I am curious is there a better more Ruby style way to achieve below:

q=[5,1,7,9,0,3,6,8,0]

for i in 0..q.size/3-1

  do one thing with q[0+i*3]

  do another one with q[1+i*3]

  third operation on q[2+i*3]

end

THX!

Code submitted in question actually works, but knowing that for in Ruby uses each under the hood, I am not sure what is the best way to make it more compact&efficient.


Solution

  • The most Ruby way to do this would probably be to use Enumerable#each_slice:

    q.each_slice(3) do |first, second, third|
      # do something with `first`
      # do another thing with `second`
      # third operation with `third`
    end
    

    For example:

    q.each_slice(3) do |first, second, third|
      p({ first:, second:, third: })
    end
    # { first: 5, second: 1, third: 7 }
    # { first: 9, second: 0, third: 3 }
    # { first: 6, second: 8, third: 0 }
    

    In general, one of the most important operations in any program is "iterating over stuff" (or more generally, traversing, transforming, filtering, building, and folding collections), and in Ruby, that is handled by the Enumerable mixin. Studying and understanding this mixin's documentation is crucial to writing good, idiomatic Ruby code.

    As a (slightly exaggerated) general rule, if you have to write a loop or manually fiddle with indices or counters in Ruby, you are very likely doing something wrong. In fact, with the powerful algorithms, data structures, and collections libraries that are shipped with most modern programming languages, that does not just apply to Ruby but almost universally.