#arrays #ruby #default-value
#массивы #ruby #значение по умолчанию
Вопрос:
Это тривиальный вопрос, не уверен, действительно ли я должен спрашивать здесь, но хотел бы узнать, есть ли у кого-нибудь более элегантный способ написать это на ruby.
У меня есть строка версии формата x.y.z
или x.y
или x
. Я хотел бы простой элегантный способ преобразовать это в массив, в который вставляется значение по умолчанию 0, если сегмент отсутствует. У меня есть несколько разных способов сделать это, но я надеялся на что-то более чистое. Atm мое текущее решение таково
version_string.split('.').each_with_index.with_object(['0','0','0']) { |(segment, i), version_array| version_array[i] = segment }
Кажется, работает нормально, и я всегда могу перейти к простому вызову метода, чтобы сделать код похожим на очистку, но что-то в использовании each_with_index
and `with_object меня немного беспокоит. Просто любопытно посмотреть, есть ли у остальной части сообщества Ruby что добавить
Комментарии:
1. Я действительно не чувствую, что это особенно элегантно, но вы можете использовать регулярное выражение для синтаксического анализа «1», «1.2», «1.2.3» в списки из 3 элементов, где недостающие числа будут равны нулю.
/(d)(?:.(d))?(?:.(d))?/.match(string)[1..-1]
например , дляstring="1.2"
того , чтобы он вернулся[1,2,nil]
. Тогда вы могли бы поработатьmap { |num| num || 0 }
над результатом, прежде чем присоединиться. Хотелось бы, чтобы был способ сделать подобноеljust
для массивов, но я ничего не вижу.2. Почему бы вам не использовать такой драгоценный камень, как versionomy ?
3.
/(d ).?(d )?.?(d )?/.match(str).captures.map {|s| s.to_i.to_s}
будет работать. @maxpleaner вы могли бы смоделировать концепцию в 2 этапаstr.scan(/d /).concat(['0','0','0']).first(3)
или['0','0','0'].unshift(*str.scan(/d /)).first(3)
4. Самая сложная вещь, которую я могу придумать,
str.split(?.). ([?0]*3)[..2]
но это предполагает, что «0» (ы) не будут изменены позже
Ответ №1:
Как насчет (минимум Ruby 2.6)
version_string.split('.').then { |x, y = '0', z = '0'| [x,y,z] }