Comment puis-je générer des zéros non significatifs dans Ruby?


238

Je produis un ensemble de fichiers numérotés à partir d'un script Ruby. Les nombres proviennent de l'incrémentation d'un compteur, mais pour les faire trier correctement dans le répertoire, j'aimerais utiliser des zéros de tête dans les noms de fichiers. En d'autres termes

file_001 ...

au lieu de

fichier_1

Existe-t-il un moyen simple d'ajouter des zéros non significatifs lors de la conversion d'un nombre en chaîne? (Je sais que je peux faire "si moins de 10 .... si moins de 100").

Réponses:


281

Si le nombre maximum de chiffres dans le compteur est connu (par exemple, n = 3 pour les compteurs 1 à 876), vous pouvez faire

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

8
Hé hé, pas la meilleure réponse, mais je ne connaissais pas le juste et j'utilise du rubis depuis des années. À votre santé!
pauliephonic

Je dois voter cela parce qu'il semble que% 03s remplisse des espaces avec des espaces pour une raison étrange (% 03d semble bien fonctionner). J'aurais pu jurer C rembourré avec des zéros dans les deux cas.
Nerdmaster

Enfin, c'est la réponse acceptée, car c'est la plus simple et la plus facile à retenir. %fonctionne mais est un usage plus général.
Nathan Long

inattendu mais plus simple
akostadinov

1
Entré ici pour savoir comment remplir un nombre de base 36. Cela fonctionne pour cela, alors que% ne semble pas. Merci!
Ethan Kaminski

344

Utilisez l' %opérateur avec une chaîne:

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

Le côté gauche est une chaîne de format printf, et le côté droit peut être une liste de valeurs, vous pouvez donc faire quelque chose comme:

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

Voici une feuille de triche au format printf que vous pourriez trouver utile pour former votre chaîne de format. Le format printf est originaire de la Cfonction printf, mais des fonctions de formatage similaires sont disponibles en perl, ruby, python, java, php, etc.


1
Génial! Donc "% s" signifie "remplacer la Nième valeur ici" et "% 03d" signifie "remplacer un nombre ici, en ajoutant autant de zéros que nécessaire pour en faire un nombre à 3 chiffres?" (Je suppose que le d signifie «chiffres».) Je vois maintenant la documentation à ce sujet ( ruby-doc.org/core/classes/String.html#M000770 ), mais c'est très concis et j'aimerais un peu d'élaboration .
Nathan Long

1
J'ai ajouté un lien vers une feuille de triche au format printf. "s" signifie "chaîne", "d" signifie "nombre décimal". Le "03" signifie "pad à 3 caractères avec des zéros"; "% 3d" serait rempli à gauche avec des espaces.
Daniel Martin

2
BTW - c'est la même chose que l'appel Kernel#sprintf, qui est documenté ici: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long

En ajoutant au commentaire de @ NathanLong, le premier exemple de cette réponse serait écrit comme sprintf("%03d", 5).
Dennis

Ce devrait être la réponse choisie.
Dan Barron

50

Ne pouvez-vous pas simplement utiliser le formatage de chaîne de la valeur avant de concaténer le nom de fichier?

"%03d" % number

Je pense que cette réponse n'ajoute rien à la réponse de @Daniel Martin, mais j'aime sa simplicité ...
svelandiag

3
Il a répondu dans la même minute que Daniel Martin et n'était donc probablement pas au courant de la duplication.
Kurt Peek

C'est parfait pour utc_offset
Abel

30

Utilisez-le String#nextcomme compteur.

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

next est relativement «intelligent», ce qui signifie que vous pouvez même opter pour

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

Merci de l'avoir signalé. C'est une méthode tellement géniale.
Weston Ganger

9

Comme indiqué par les autres réponses, "%03d" % numberfonctionne assez bien, mais cela va à l'encontre du guide de style rubocop ruby :

Privilégiez l'utilisation de sprintf et de son format d'alias par rapport à la méthode String #% assez cryptique

Nous pouvons obtenir le même résultat d'une manière plus lisible en utilisant ce qui suit:

format('%03d', number)

1
Si votre objectif est d'apprendre une fonction obscure du langage Ruby, utilisez l'alias format. Si votre objectif est de rendre votre code facile à comprendre, vous devez l'utiliser sprintf, car il fait partie de la bibliothèque C standard. Ce nom est utilisé dans tous les langages de programmation. Beaucoup plus de gens comprennent ce que sprintffait, par rapport au nombre de ceux qui savent que formatc'est un pseudonyme. Ce n'est pas parce que quelque chose fait partie de RuboCop qu'il est intrinsèquement bon ou mauvais. Choisissez les règles les plus pertinentes pour votre projet. '%03d' % numberest encore plus facile à lire.
Tilo

1
J'ai parcouru cette même boucle, passant "%02d" % numà sprintf(...), puis à format(...)la suggestion de RuboCop. J'ai alors décidé que sprintfc'était plus conventionnel que format, donc mis à jour rubocop.yml avec Style/FormatString: EnforcedStyle: sprintfet maintenant je dors bien la nuit.
David Hempy

1

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

Les sorties

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.