Como posso gerar zeros à esquerda em Ruby?

238

Estou produzindo um conjunto de arquivos numerados de um script Ruby. Os números vêm do incremento de um contador, mas para classificá-los bem no diretório, eu gostaria de usar zeros à esquerda nos nomes dos arquivos. Em outras palavras

file_001 ...

ao invés de

arquivo_1

Existe uma maneira simples de adicionar zeros à esquerda ao converter um número em uma string? (Eu sei que posso fazer "se for menor que 10 ... se for menor que 100").

Nathan Long
fonte

Respostas:

281

Se o número máximo de dígitos no contador for conhecido (por exemplo, n = 3 para os contadores 1..876), você poderá

str = "file_" + i.to_s.rjust(n, "0")
alex.zherdev
fonte
8
Heh heh, não é a melhor resposta, mas eu não sabia sobre o just e estou usando o ruby ​​há anos. Felicidades!
21139 pauliephonic
É preciso votar isso porque parece que% 03s se junta a espaços por algum motivo estranho (% 03d parece funcionar bem). Eu poderia jurar C preenchido com zeros nos dois casos.
Nerdmaster 21/10
Finalmente, mudei para que seja a resposta aceita, porque é a mais simples e mais fácil de lembrar. %funciona, mas é de propósito mais geral.
Nathan Long
inesperado, mas mais fácil
akostadinov 22/10/2015
1
Vim aqui para saber como preencher um número base 36. Isso funciona para isso, enquanto% parece que não. Obrigado!
Ethan Kaminski
344

Use o %operador com uma string:

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

O lado esquerdo é uma string de formato printf, e o lado direito pode ser uma lista de valores, portanto, você pode fazer algo como:

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

Aqui está uma folha de dicas no formato printf, que você pode achar útil na formação da string de formato. O formato printf é originalmente da Cfunção printf, mas funções de formatação semelhantes estão disponíveis em perl, ruby, python, java, php, etc.

Daniel Martin
fonte
1
Ótimo! Então "% s" significa "substitua o valor N-ésimo aqui" e "% 03d" significa "substitua um número aqui, adicionando quantos zeros forem necessários para torná-lo um número de três dígitos?" (Suponho que d significa "dígitos".) Agora vejo a documentação sobre isso agora ( ruby-doc.org/core/classes/String.html#M000770 ), mas é muito conciso e eu gostaria de um pouco de elaboração .
Nathan Long
1
Eu adicionei um link para uma folha de dicas no formato printf. "s" significa "string", "d" significa "número decimal". O "03" significa "preenchimento de 3 caracteres com zeros"; "% 3d" preencheria à esquerda com espaços.
1013 Daniel Martin
2
BTW - este é o mesmo que chamar Kernel#sprintf, que está documentado aqui: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long
Adicionando ao comentário de @ NathanLong, o primeiro exemplo nesta resposta seria escrito como sprintf("%03d", 5).
1111 Dennis
Essa deve ser a resposta selecionada.
Dan Barron
50

Você não pode simplesmente usar a formatação de string do valor antes de concat o nome do arquivo?

"%03d" % number
Ólafur Waage
fonte
Eu acho que essa resposta não acrescenta nada para a resposta de @ Daniel Martin, no entanto I como sua simplicidade ...
svelandiag
3
Ele respondeu no mesmo minuto em que Daniel Martin provavelmente não tinha conhecimento da duplicação.
Kurt Peek
Isto é perfeito para utc_offset
Abel
30

Use String#nextcomo contador.

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

next é relativamente "inteligente", o que significa que você pode até

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003
testr
fonte
Obrigado por apontar isso. Este é um método tão impressionante.
Weston Ganger 20/01
9

Conforme declarado nas outras respostas, "%03d" % numberfunciona muito bem, mas vai contra o guia de estilo do rubocop ruby :

Favorecer o uso do sprintf e seu formato alternativo sobre o método String #% bastante enigmático

Podemos obter o mesmo resultado de maneira mais legível usando o seguinte:

format('%03d', number)
Rodrigo Vasconcelos
fonte
1
Se seu objetivo é aprender um recurso obscuro da linguagem Ruby, use o alias format. Se seu objetivo é facilitar a compreensão do seu código, você deve usá- sprintflo, porque ele faz parte da biblioteca C padrão. Este nome é usado em linguagens de programação. Muito mais pessoas entendem o que sprintffazem, em comparação com o número que sabe que formaté um alias para ele. Só porque algo faz parte do RuboCop não o torna inerentemente certo ou errado. Escolha as regras que fazem mais sentido para o seu projeto. '%03d' % numberé ainda mais fácil de ler.
Tilo
1
Passei pelo mesmo loop, mudando "%02d" % numpara sprintf(...), em seguida, de format(...)acordo com a sugestão do RuboCop. Decidi então que sprintfera mais convencional do que o formatrubocop.yml atualizado Style/FormatString: EnforcedStyle: sprintfe que agora durmo bem à noite.
David Hempy
1

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

Saídas

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

Ivan
fonte