присоединиться к перечислимому для создания строки в Ruby

Массивы Ruby имеют метод #join, который создает строку, объединяя элементы массива и добавляя необязательный разделитель.

Другие перечисления, такие как диапазоны, не имеют такого же метода.

Вы можете эмулировать поведение, используя #inject, например.

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

Есть ли лучший способ присоединиться к перечислимым? Был ли #join опущен по определенной причине?

ИЗМЕНИТЬ:

Одна вещь, о которой я бы беспокоился, - это копирование массивного перечисляемого в массив. Конечно, это редко используется, но все же. Например:

(1 .. 1_000_000_000_000_000).to_a.join

Поэтому меня особенно интересуют решения, которые не требуют создания массива со всеми значениями в качестве промежуточного шага.


person Erik Madsen    schedule 14.09.2018    source источник
comment
Был ли #join опущен по определенной причине - некоторые перечисляемые числа бесконечны. Массивы никогда не бывают.   -  person Sergio Tulentsev    schedule 14.09.2018
comment
Я сомневаюсь, что понимаю, о чем спрашивают в отредактированной части. Если вы хотите присоединиться без преобразования в массив, вы можете inject сделать так, как сделали.   -  person Aleksei Matiushkin    schedule 14.09.2018
comment
JFYI, предложенная вами замена на inject не работает. Но да, это правильный подход.   -  person Sergio Tulentsev    schedule 14.09.2018
comment
Был ли #join пропущен по определенной причине -- присутствовал ли #join когда-либо?   -  person sawa    schedule 14.09.2018
comment
@СергиоТуленцев спасибо. Починил это.   -  person Erik Madsen    schedule 14.09.2018
comment
@sawa Я так не думаю. Под опущенным я подразумеваю опущенное.   -  person Erik Madsen    schedule 14.09.2018
comment
@SergioTulentsev хороший момент. Однако перечисления предлагают некоторые методы агрегирования, например #count. Он предлагает специализированный вывод для бесконечных случаев.   -  person Erik Madsen    schedule 14.09.2018


Ответы (2)


Используйте Array#join:

('a'..'z').to_a.join(' some separator ')

Или (фактически то же самое):

[*'a'..'z'].join(' some separator ')
person Aleksei Matiushkin    schedule 14.09.2018
comment
Спасибо за Ваш ответ. Это абсолютно решение. Пожалуйста, смотрите мое редактирование для более подробной информации. - person Erik Madsen; 14.09.2018
comment
@SergioTulentsev как в ОП, что тоже несколько выше :) - person Aleksei Matiushkin; 14.09.2018

person    schedule
comment
Классное использование *. Но семантика отличается от соединения, потому что разделитель вставляется перед 'a' в выходных данных. - person Erik Madsen; 14.09.2018
comment
Хорошо, я исправил пример в вопросе. Предполагается, что это join семантика. - person Erik Madsen; 14.09.2018