Як я можу вивести провідні нулі в Ruby?


238

Я виводжу набір пронумерованих файлів із сценарію Ruby. Цифри походять від збільшення лічильника, але для того, щоб вони добре сортувались в каталозі, я хотів би використовувати провідні нулі у назви файлів. Іншими словами

file_001 ...

замість

файл_1

Чи є простий спосіб додати провідні нулі при перетворенні числа в рядок? (Я знаю, що можу зробити "якщо менше 10 .... якщо менше 100").

Відповіді:


281

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

str = "file_" + i.to_s.rjust(n, "0")

8
Хе-хе, не найкраща відповідь, але я не знав про суровість і роками користувався рубіном. Ура!
pauliephonic

Я повинен проголосувати це, тому що здається, що% 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" означає "замінити число тут, додавши стільки нулів, скільки потрібно, щоб зробити його 3-значним числом?" (Я здогадуюсь, що d означає "цифри".) Я бачу документацію щодо цього зараз ( ruby-doc.org/core/classes/String.html#M000770 ), але це дуже стисло, і я хотів би трохи детальніше. .
Натан Лонг

1
Я додав посилання на шпаргалку формату printf. "s" означає "рядок", "d" означає "десятковий номер". "03" означає "майданчик до 3 символів із нулями"; "% 3d" буде прокладено зліва пробілами.
Даніель Мартін

2
BTW - це те саме, що дзвонити 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
Abel

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

Дякуємо, що вказали на це. Це такий приголомшливий метод.
Вестон Гангер

9

Як зазначено в інших відповідях, "%03d" % numberпрацює досить добре, але це суперечить керівництву зі стилю rubycop rubycop :

Віддавайте перевагу використанню sprintf та його псевдоніму у форматі досить криптованого String #%

Ми можемо отримати той же результат більш читабельним способом, використовуючи наступне:

format('%03d', number)

1
Якщо ваша мета - вивчити незрозумілу функцію мови Ruby, тоді використовуйте псевдонім format. Якщо ваша мета - зробити ваш код легким для розуміння, вам слід скористатися sprintf, оскільки він є частиною стандартної С-бібліотеки. Ця назва використовується в мовах програмування. Набагато більше людей розуміють, що 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]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.