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.
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.