Bagaimana saya bisa menghasilkan angka nol di Ruby?

238

Saya mengeluarkan serangkaian file bernomor dari skrip Ruby. Angka-angka tersebut berasal dari penambahan penghitung, tetapi untuk membuatnya tersortir dengan baik di direktori, saya ingin menggunakan angka nol di depan nama file. Dengan kata lain

file_001 ...

dari pada

file_1

Apakah ada cara sederhana untuk menambahkan angka nol di depan saat mengonversi angka menjadi sebuah string? (Saya tahu saya bisa melakukan "jika kurang dari 10 ... jika kurang dari 100").

Nathan Long
sumber

Jawaban:

281

Jika jumlah maksimum digit di penghitung diketahui (misalnya, n = 3 untuk penghitung 1..876), Anda dapat melakukan

str = "file_" + i.to_s.rjust(n, "0")
alex.zherdev
sumber
8
Heh heh, bukan jawaban terbaik, tapi saya tidak tahu tentang keadilan dan saya sudah menggunakan ruby ​​selama bertahun-tahun. Bersulang!
pauliephonic
Harus memilih ini karena sepertinya% 03s cocok dengan spasi untuk beberapa alasan aneh (% 03d tampaknya berfungsi dengan baik). Saya bisa bersumpah C empuk dengan nol dalam kedua kasus.
Nerdmaster
Akhirnya beralih ini menjadi jawaban yang diterima karena ini adalah yang paling sederhana dan paling mudah diingat. %berfungsi tetapi merupakan tujuan yang lebih umum.
Nathan Long
tak terduga tetapi termudah
akostadinov
1
Datang ke sini untuk cara memasang nomor base 36. Ini berfungsi untuk itu, sedangkan% sepertinya tidak. Terima kasih!
Ethan Kaminski
344

Gunakan %operator dengan string:

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

Sisi kiri adalah string format printf, dan sisi kanan dapat berupa daftar nilai, sehingga Anda bisa melakukan sesuatu seperti:

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

Berikut lembar contekan format printf yang mungkin berguna untuk membentuk string format Anda. Format printf berasal dari Cfungsi printf, tetapi fungsi format serupa tersedia dalam perl, ruby, python, java, php, dll.

Daniel Martin
sumber
1
Bagus! Jadi "% s" berarti "mengganti nilai N di sini," dan "% 03d" berarti "mengganti angka di sini, menambahkan sebanyak nol yang diperlukan untuk menjadikannya angka 3 digit?" (Saya menduga huruf d berarti "digit.") Saya melihat dokumentasi tentang ini sekarang ( ruby-doc.org/core/classes/String.html#M000770 ), tapi sangat ringkas dan saya ingin sedikit elaborasi. .
Nathan Long
1
Saya menambahkan tautan ke lembar contekan format printf. "s" berarti "string", "d" berarti "angka desimal". "03", berarti "pad 3 karakter dengan nol"; "% 3d" akan menempel di sebelah kiri dengan spasi.
Daniel Martin
2
BTW - ini sama dengan panggilan Kernel#sprintf, yang didokumentasikan di sini: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long
Menambahkan ke komentar @ NathanLong, contoh pertama dalam jawaban ini akan ditulis sebagai sprintf("%03d", 5).
Dennis
Ini harus menjadi jawaban yang dipilih.
Dan Barron
50

Tidak bisakah Anda hanya menggunakan pemformatan string dari nilai sebelum Anda menggabungkan nama file?

"%03d" % number
Ólafur Waage
sumber
Saya pikir jawaban ini tidak menambahkan apa pun ke jawaban @Daniel Martin, namun saya suka kesederhanaannya ...
svelandiag
3
Dia menjawab pada saat yang sama dengan Daniel Martin jadi mungkin tidak menyadari duplikasi itu.
Kurt Peek
Ini sempurna untuk utc_offset
Abel
30

Gunakan String#nextsebagai penghitung.

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

next relatif 'pintar', yang berarti Anda bahkan bisa melakukannya

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003
testr
sumber
Terima kasih telah menunjukkan ini. Ini adalah metode yang luar biasa.
Weston Ganger
9

Seperti yang dinyatakan oleh jawaban lain, "%03d" % numberbekerja cukup baik, tetapi itu bertentangan dengan panduan gaya rubocop ruby :

Mendukung penggunaan sprintf dan format aliasnya di atas metode String #% yang cukup samar

Kami dapat memperoleh hasil yang sama dengan cara yang lebih mudah dibaca menggunakan yang berikut:

format('%03d', number)
Rodrigo Vasconcelos
sumber
1
Jika tujuan Anda adalah mempelajari fitur bahasa Ruby yang tidak jelas, gunakan alias format. Jika tujuan Anda adalah membuat kode Anda mudah dimengerti, Anda harus menggunakannya sprintf, karena itu adalah bagian dari C-library standar. Nama ini digunakan di seluruh bahasa pemrograman. Cara lebih banyak orang mengerti apa yang sprintfdilakukan, dibandingkan dengan jumlah yang tahu itu formatadalah alias untuk itu. Hanya karena sesuatu adalah bagian dari RuboCop tidak menjadikannya benar atau salah. Pilih aturan yang paling masuk akal untuk proyek Anda. '%03d' % numberbahkan lebih mudah dibaca.
Tilo
1
Saya melalui loop yang sama ini, berubah "%02d" % nummenjadi sprintf(...), lalu format(...)sesuai saran RuboCop. Saya kemudian memutuskan bahwa sprintfitu lebih konvensional daripada format, jadi diperbarui dengan rubocop.yml Style/FormatString: EnforcedStyle: sprintfdan sekarang saya tidur nyenyak di malam hari.
David Hempy
1

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

Keluaran

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

Ivan
sumber