Search code examples
rubystringenumerable

join enumerable to produce string in Ruby


Ruby arrays have the #join method that produces a string by joining the elements of the array, adding an optional separator.

Other enumerables such as ranges don't have the same method.

You could emulate the behaviour using #inject, e.g.

('a'..'z').inject('') do |acc, s| 
  if acc.empty?
    s
  else
    acc << ' some separator ' << s.to_s  
  end
end

Is there a better way to join enumerables? Was #join omitted for a particular reason?

EDIT:

One thing I would be concerned about would be copying a massive enumerable to an array. Of course that's seldom a use case, but still. For instance:

(1 .. 1_000_000_000_000_000).to_a.join

Therefore I'm particularly interested in solutions that don't require generating an array with all the values as an intermediate step.


Solution

  • The code within your question is already as optimal as it gets, but it's possible to remove the condition inside your block:

    e = ('a'..'z').to_enum
    
    joined_string = e.reduce { |acc, str| acc << ' some separator ' << str }.to_s
    

    Without passing an argument to #reduce, the first time the block gets called, acc and str would represent the first two elements of the enumerable. The additional .to_s at the end is to ensure that an empty string is returned if the enumerable is empty.