Reputation: 2014
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.
Upvotes: 2
Views: 1179
Reputation: 173572
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.
Upvotes: 1
Reputation: 10251
> [*'a'..'z'] * ' some separator '
#=> "a some separator b some separator c some separator d some separator e some separator f some separator g some separator h some separator i some separator j some separator k some separator l some separator m some separator n some separator o some separator p some separator q some separator r some separator s some separator t some separator u some separator v some separator w some separator x some separator y some separator z"
Upvotes: 1
Reputation: 121000
Use Array#join
:
('a'..'z').to_a.join(' some separator ')
Or (effectively the same):
[*'a'..'z'].join(' some separator ')
Upvotes: 3