Come posso generare zero iniziali in Ruby?


238

Sto producendo una serie di file numerati da uno script di Ruby. I numeri provengono dall'incremento di un contatore, ma per ordinarli bene nella directory, mi piacerebbe usare zeri iniziali nei nomi dei file. In altre parole

file_001 ...

invece di

file_1

Esiste un modo semplice per aggiungere zeri iniziali durante la conversione di un numero in una stringa? (So ​​di poter fare "se meno di 10 .... se meno di 100").

Risposte:


281

Se è noto il numero massimo di cifre nel contatore (ad es. N = 3 per i contatori 1..876), è possibile eseguire

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

8
Eh eh, non la risposta migliore, ma non sapevo di rjust e uso ruby ​​da anni. Saluti!
pauliephonic,

Devo votare questo perché sembra che% 03s pad con spazi per qualche strana ragione (% 03d sembra funzionare bene). Avrei potuto giurare C imbottito di zeri in entrambi i casi.
Nerdmaster,

Finalmente questa è stata la risposta accettata perché è la più semplice e facile da ricordare. %funziona ma ha uno scopo più generale.
Nathan Long,

inaspettato ma più semplice
Akostadinov il

1
Sono venuto qui per come riempire un numero 36 di base. Funziona per questo, mentre% sembra che non lo farà. Grazie!
Ethan Kaminski,

344

Utilizzare l' %operatore con una stringa:

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

Il lato sinistro è una stringa di formato printf e il lato destro può essere un elenco di valori, quindi è possibile fare qualcosa del tipo:

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

Ecco un cheat sheet in formato printf che potresti trovare utile nel formare la tua stringa di formato. Il formato printf è originariamente dalla Cfunzione printf, ma funzioni di formattazione simili sono disponibili in perl, ruby, python, java, php, ecc.


1
Grande! Quindi "% s" significa "sostituisci l'ennesimo valore qui" e "% 03d" significa "sostituisci un numero qui, aggiungendo tutti gli zeri necessari per renderlo un numero di 3 cifre?" (Immagino che la d significhi "cifre".) Ora vedo la documentazione su questo ( ruby-doc.org/core/classes/String.html#M000770 ), ma è molto concisa e vorrei una piccola elaborazione .
Nathan Long,

1
Ho aggiunto un collegamento a un cheat sheet in formato printf. "s" significa "stringa", "d" significa "numero decimale". "03" significa "pad a 3 caratteri con zeri"; "% 3d" si sposta sulla sinistra con spazi.
Daniel Martin,

2
A proposito, questo è lo stesso di chiamare Kernel#sprintf, che è documentato qui: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long,

Aggiungendo al commento di @ NathanLong, il primo esempio in questa risposta sarebbe scritto come sprintf("%03d", 5).
Dennis,

Questa dovrebbe essere la risposta selezionata.
Dan Barron,

50

Non puoi semplicemente utilizzare la formattazione di stringa del valore prima di concatenare il nome file?

"%03d" % number

Penso che questa risposta non aggiunga nulla alla risposta di @Daniel Martin, tuttavia mi piace la sua semplicità ...
svelandiag

3
Ha risposto nello stesso minuto di Daniel Martin, quindi probabilmente non era a conoscenza della duplicazione.
Kurt Peek,

Questo è perfetto per utc_offset
Abel il

30

Utilizzare String#nextcome contatore.

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

next è relativamente "intelligente", il che significa che puoi anche provare

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003

Grazie per averlo segnalato. Questo è un metodo fantastico.
Weston Ganger,

9

Come affermato dalle altre risposte, "%03d" % numberfunziona abbastanza bene, ma va contro la guida di stile rubocop ruby :

Favorire l'uso di sprintf e il suo formato alias rispetto al metodo String #% abbastanza criptico

Possiamo ottenere lo stesso risultato in un modo più leggibile usando quanto segue:

format('%03d', number)

1
Se il tuo obiettivo è imparare un'oscura funzionalità del linguaggio Ruby, usa l'alias format. Se il tuo obiettivo è quello di rendere il tuo codice facile da capire, dovresti usarlo sprintf, perché fa parte della libreria C standard. Questo nome viene utilizzato in tutti i linguaggi di programmazione. Il modo in cui più persone capiscono cosa sprintffa, rispetto al numero che sa che formatè un alias per questo. Solo perché qualcosa fa parte di RuboCop non lo rende intrinsecamente giusto o sbagliato. Scegli le regole che hanno più senso per il tuo progetto. '%03d' % numberè ancora più facile da leggere.
Tilo,

1
Ho attraversato questo stesso ciclo, passando "%02d" % numa sprintf(...), quindi a format(...)suggerimento di RuboCop. Ho quindi deciso che sprintfera più convenzionale di format, quindi aggiornato con rubocop.yml Style/FormatString: EnforcedStyle: sprintfe ora dormo bene la notte.
David Hempy,

1

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

Uscite

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.