Как вывести ведущие нули в Ruby?

238

Я выводю набор пронумерованных файлов из сценария Ruby. Числа получены в результате увеличения счетчика, но чтобы они хорошо сортировались в каталоге, я бы хотел использовать начальные нули в именах файлов. Другими словами

file_001 ...

вместо того

file_1

Есть ли простой способ добавить начальные нули при преобразовании числа в строку? (Я знаю, что могу сделать «если меньше 10 .... если меньше 100»).

Натан Лонг
источник

Ответы:

281

Если максимальное количество цифр в счетчике известно (например, n = 3 для счетчиков 1..876), вы можете сделать

str = "file_" + i.to_s.rjust(n, "0")
alex.zherdev
источник
8
Хе-хе, не самый лучший ответ, но я не знал о rjust и уже много лет использую ruby. Ура!
Полифонический
Должен проголосовать, потому что кажется, что% 03s с пробелами по какой-то странной причине (% 03d, кажется, работает нормально). Я мог бы поклясться С, дополненный нулями в обоих случаях.
Nerdmaster
В конце концов переключил это, чтобы быть принятым ответом, потому что это самый простой и легкий для запоминания. %работает, но имеет более общее назначение.
Натан Лонг
неожиданно, но проще всего
акостадинов
1
Пришел сюда для того, чтобы дополнить базу 36 номером. Это работает для этого, тогда как%, похоже, не будет. Спасибо!
Итан Камински
344

Используйте %оператор со строкой:

irb(main):001:0> "%03d" % 5
=> "005"

Левая сторона - это строка формата printf, а правая часть может быть списком значений, так что вы можете сделать что-то вроде:

irb(main):002:0> filename = "%s/%s.%04d.txt" % ["dirname", "filename", 23]
=> "dirname/filename.0023.txt"

Вот шпаргалка формата printf, которую вы можете найти полезной при формировании строки формата. Формат printf изначально взят из Cфункции printf, но аналогичные функции форматирования доступны в perl, ruby, python, java, php и т. Д.

Даниэль Мартин
источник
1
Большой! Таким образом, «% s» означает «подставить здесь N-е значение», а «% 03d» означает «подставить здесь число, добавив столько нулей, сколько необходимо, чтобы сделать его трехзначным числом?» (Я предполагаю, что d означает «цифры».) Теперь я вижу документацию по этому вопросу ( ruby-doc.org/core/classes/String.html#M000770 ), но она очень лаконична, и я хотел бы немного проработать ,
Натан Лонг
1
Я добавил ссылку на шпаргалку в формате printf. «s» означает «строка», «d» означает «десятичное число». «03» означает «дополнить до 3 символов нулями»; «% 3d» будет заполняться слева пробелами.
Даниэль Мартин
2
Кстати, это то же самое, что звонить Kernel#sprintf, что задокументировано здесь: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Натан Лонг
Если добавить комментарий @ NathanLong, первый пример в этом ответе будет записан как sprintf("%03d", 5).
Деннис
Это должен быть выбранный ответ.
Дэн Баррон,
50

Разве вы не можете просто использовать строковое форматирование значения перед тем, как указать имя файла?

"%03d" % number
Олафур Вааге
источник
Я думаю, что этот ответ ничего не добавляет к ответу @Daniel Martin, однако мне нравится его простота ...
svelandiag
3
Он ответил в ту же минуту, что и Даниэль Мартин, поэтому, вероятно, не знал о дублировании.
Курт Пик
Это идеально подходит для utc_offset
Авель
30

Используйте String#nextв качестве счетчика.

>> n = "000"
>> 3.times { puts "file_#{n.next!}" }
file_001
file_002
file_003

next является относительно «умным», то есть вы можете даже пойти на

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003
testr
источник
Спасибо за указание на это. Это такой потрясающий метод.
Уэстон Гангер
9

Как указано в других ответах, "%03d" % numberработает довольно хорошо, но это идет вразрез с руководством по рубиновому стилю ruby :

Воспользуйтесь использованием sprintf и его псевдонима над довольно загадочным методом String #%

Мы можем получить тот же результат более читабельным способом, используя следующее:

format('%03d', number)
Родриго Васконселос
источник
1
Если ваша цель состоит в изучении малопонятного языка Ruby, используйте псевдоним format. Если ваша цель состоит в том, чтобы сделать ваш код легким для понимания, вы должны использовать его sprintf, потому что он является частью стандартной C-библиотеки. Это имя используется во всех языках программирования. Чем больше людей понимают, что sprintfделает, по сравнению с числом людей, которые знают, что formatэто псевдоним для этого. Тот факт, что что-то является частью RuboCop, не делает его по сути правильным или неправильным. Выберите правила, наиболее подходящие для вашего проекта. '%03d' % numberеще легче читать.
Тило
1
Я прошел через этот же цикл, изменив "%02d" % numна sprintf(...), а затем format(...)на предложение, предложенное RuboCop. Затем я решил, что sprintfэто более привычно format, поэтому обновил rubocop.yml Style/FormatString: EnforcedStyle: sprintfи теперь я сплю по ночам.
Дэвид Хемпи
1

filenames = '000'.upto('100').map { |index| "file_#{index}" }

Выходы

[file_000, file_001, file_002, file_003, ..., file_098, file_099, file_100]

Иван
источник