Comment convertir un Int en une chaîne d'une longueur donnée avec des zéros non significatifs à aligner?


98

Comment puis-je convertir un Inten un long de 7 caractères String, de sorte qu'il 123soit transformé en "0000123"?

Réponses:


221

La bibliothèque Java a une assez bonne prise en charge (comme en excellent) du formatage des nombres qui est accessible à partir de la classe String enrichie par StringOps :

scala> "%07d".format(123)
res5: String = 0000123

scala> "%07d".formatLocal(java.util.Locale.US, 123)
res6: String = 0000123

Edit post Scala 2.10 : comme suggéré par fommil, à partir de 2.10, il existe également un interpolateur de chaîne de formatage (ne prend pas en charge la localisation):

val expr = 123
f"$expr%07d"
f"${expr}%07d"

Modifier avril 2019:

  • Si vous voulez des espaces de début, et non zéro, laissez simplement le 0dans le spécificateur de format. Dans le cas ci-dessus, il serait f"$expr%7d".Testé dans 2.12.8 REPL. Pas besoin de faire le remplacement de chaîne comme suggéré dans un commentaire, ni même de mettre un espace explicite devant 7comme suggéré dans un autre commentaire.
  • Si la longueur est variable, s"%${len}d".format("123")

6
Ben, dhg, merci pour les votes positifs, vous êtes une foule difficile cependant! Je pense que nous pouvons encore apprendre quelque chose des autres réponses, et le système de vote se charge de savoir quelle réponse est pertinente.
huynhjl

8
vous n'avez pas besoin d'être aussi explicite, vous pouvez écrire f"$a%07d"(si vous avez un val/ var adans la portée).
fommil le

1
@fommil, en effet, ce n'était pas encore là quand j'ai posté la réponse initiale, mais j'utiliserais aussi l'interpolateur f maintenant qu'il existe.
huynhjl

Si vous voulez des espaces de regex string.replaceAll("\\G0", " ")
début

1
Si vous voulez des espaces de début au lieu de zéros de début, utilisez "% 7d".format(123).
Erik van Oosten

36

Réponse courte:

"1234".reverse.padTo(7, '0').reverse

Longue réponse:

Scala StringOps (qui contient un bel ensemble de méthodes que les objets de chaîne Scala ont en raison de conversions implicites) a une padTométhode, qui ajoute un certain nombre de caractères à votre chaîne. Par exemple:

"aloha".padTo(10,'a')

Reviendra "alohaaaaaa". Notez que le type d'élément d'une chaîne est un Char, d'où les guillemets simples autour du 'a'.

Votre problème est un autre bit puisque vous devez préfixer caractères au lieu de annexant eux. C'est pourquoi vous devez inverser la chaîne, ajouter les caractères de remplissage (vous les ajouteriez maintenant puisque la chaîne est inversée), puis inverser le tout pour obtenir le résultat final.

J'espère que cela t'aides!


14
Utilisez .mkString pour redevenir une chaîne
samthebest

2
ou utilisez le caractère 'a'
Lawrence Wagerfield

29

Le paddingest désigné par %02dfor 0pour être préfixé pour faire la longueur 2:

scala> val i = 9 
i: Int = 9

scala> val paddedVal = f"${num}%02d"
paddedVal: String = 09

scala> println(paddedVal)             
09

Dans cette ligne val paddedVal = f"${num}%02d"devrait être changé numpouri
mjbsgll

f"$num%02d"(pas de parenthèses nécessaires ici)
Hartmut P.

9

huynhjl m'a battu à la bonne réponse, alors voici une alternative:

"0000000" + 123 takeRight 7

Cela échouera pour les nombres supérieurs à 10M: "0000000" + Int.MaxValue takeRight 7=> 7483647. Bien que "techniquement" correcte par l'interprétation littérale de la question, il est peu probable que le lecteur ne veuille pas que le nombre complété s'étende au-delà de 7 chiffres si le nombre est aussi grand.
Emil Lundberg

Eh bien, vous pourriez dire que cette solution est meilleure car au moins les chiffres sont toujours correctement alignés dans ce cas particulier, contrairement à la solution acceptée. Le but de la question est de faire aligner correctement les chiffres.
Luigi Plinge

3
def leftPad(s: String, len: Int, elem: Char): String = {
 elem.toString * (len - s.length()) + s
}

1

Au cas où ce Q&A deviendrait le recueil canonique,

scala> import java.text._
import java.text._

scala> NumberFormat.getIntegerInstance.asInstanceOf[DecimalFormat]
res0: java.text.DecimalFormat = java.text.DecimalFormat@674dc

scala> .applyPattern("0000000")

scala> res0.format(123)
res2: String = 0000123

1

Avez-vous besoin de gérer des nombres négatifs? Sinon, je ferais juste

def str(i: Int) = (i % 10000000 + 10000000).toString.substring(1)

ou

def str(i: Int) = { val f = "000000" + i; f.substring(f.length() - 7) }

Sinon, vous pouvez utiliser NumberFormat:

val nf = java.text.NumberFormat.getIntegerInstance(java.util.Locale.US)
nf.setMinimumIntegerDigits(7)
nf.setGroupingUsed(false)
nf.format(-123)
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.