Comment remplir une valeur avec des zéros non significatifs?


395

Quelle est la méthode recommandée pour remplir une valeur en JavaScript? J'imagine que je pourrais créer une fonction personnalisée pour ajouter des zéros à une valeur transtypée, mais je me demande s'il existe un moyen plus direct de le faire?

Remarque: Par "zerofilled", je veux dire dans le sens de base de données du mot (où une représentation zerofilled à 6 chiffres du nombre 5 serait "000005").


Ce n'est vraiment pas assez d'informations pour répondre. L'instance la plus courante de «remplissage nul» consiste probablement à ajouter des zéros aux dates: 5/1/2008> 05/01/2008. C'est ça que tu veux dire?
Triptyque

6
Pour les applications de nœuds, utilisez npm install sprintf-js-le et exigez-le dans le fichier dont vous avez besoin:sprintf('%0d6', 5);
Droogans

function padWithZeroes(n, width) { while(n.length<width) n = '0' + n; return n;} ... en supposant qu'il nne soit pas négatif
Paolo

@Paolo cette fonction ne fonctionne pas si n est numérique. Vous auriez besoin de convertir n en une chaîne avant le whileafin d'accéder àn.length
Nick F

1
Un liner sans boucles ni bibliothèques Math ou While? mynum = "0".repeat((n=6-mynum.toString().length)>0?n:0)+mynum;
Adam Whateverson,

Réponses:


226

Note aux lecteurs!

Comme l'ont souligné les commentateurs, cette solution est «intelligente», et comme les solutions intelligentes le sont souvent, elle est gourmande en mémoire et relativement lente. Si les performances vous préoccupent, n'utilisez pas cette solution!

Potentiellement obsolète : ECMAScript 2017 inclut String.prototype.padStart et Number.prototype.toLocaleString existe depuis ECMAScript 3.1. Exemple:

var n=-0.1;
n.toLocaleString('en', {minimumIntegerDigits:4,minimumFractionDigits:2,useGrouping:false})

... affichera "-0000.10".

// or 
const padded = (.1+"").padStart(6,"0");
`-${padded}`

... affichera "-0000.1".

Une fonction simple est tout ce dont vous avez besoin

function zeroFill( number, width )
{
  width -= number.toString().length;
  if ( width > 0 )
  {
    return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
  }
  return number + ""; // always return a string
}

vous pouvez faire cuire cela dans une bibliothèque si vous souhaitez conserver l'espace de noms ou autre. Comme avec l'extension de jQuery .


1
Maintenant, il vous suffit de prendre soin des nombres comme 50.1234 et vous avez une version lisible de ma solution ci-dessous! Cependant, j'ai supposé que nous venions de laisser un rembourrage, pas un rembourrage global.
coderjoe

7
Pas un fan de créer un nouveau tableau chaque fois que vous souhaitez ajouter une valeur. Les lecteurs doivent être conscients de l'impact potentiel de la mémoire et du GC s'ils effectuent de gros # de ceux-ci (par exemple sur un serveur node.js qui effectue des milliers de ces opérations par seconde. La réponse de @ profitehlolz semble être la meilleure solution .)
broofa

6
Cela ne fonctionne pas pour les valeurs négatives: zeroFill (-10, 7) -> "0000-10"
digitalbath

2
Mesure des performances parmi les trois meilleures réponses ici: jsperf.com/left-zero-pad
tomsmeding

12
Depuis ECMAScript 2017, il existe une fonction intégrée padStart .
Tomas Nikodym

321

Manière simple. Vous pouvez ajouter une multiplication de chaînes pour le pad et le transformer en fonction.

var pad = "000000";
var n = '5';
var result = (pad+n).slice(-pad.length);

En tant que fonction,

function paddy(num, padlen, padchar) {
    var pad_char = typeof padchar !== 'undefined' ? padchar : '0';
    var pad = new Array(1 + padlen).join(pad_char);
    return (pad + num).slice(-pad.length);
}
var fu = paddy(14, 5); // 00014
var bar = paddy(2, 4, '#'); // ###2

95
C'est une très bonne solution, la meilleure que j'ai vue. Pour plus de clarté, voici une version plus simple que j'utilise pour remplir les minutes dans le formatage de l'heure: ('0' + minutes) .slice (-2)
Luke Ehresman

17
C'est 5 fois plus lent que l'implémentation avec une boucle while: gist.github.com/4382935
andrewrk

42
Cela a un FATAL FLAW avec des nombres plus importants que prévu - ce qui est un phénomène extrêmement courant. Par exemple, les paddy (888, 2)rendements 88et pas 888comme requis. Cette réponse ne gère pas non plus les nombres négatifs.
Brock Adams

8
@BrockAdams, le zerofill est généralement utilisé pour les cas de nombre / formatage à largeur fixe - donc je pense qu'il serait en fait moins probable (ou même sans problème) si on lui donne un numéro à 3 chiffres lors de la tentative de zerofill à 2 chiffres.
Seaux

1
("000000" + somenum) .substr (-6,6) où le nombre de zéros et les -6,6 correspondent à la largeur du tampon. Même idée mais la tranche prend un paramètre de moins; Je ne sais pas si la tranche est plus rapide ou plus lente que subtr. Bien sûr, ma solution n'a pas besoin d'affectation de variables.
slartibartfast

315

Je ne peux pas croire toutes les réponses complexes ici ... Utilisez simplement ceci:

var zerofilled = ('0000'+n).slice(-4);

27
Bon sauf pour les nombres négatifs et les nombres de plus de 4 chiffres.
wberry

12
@wberry, ce n'était pas destiné à être un code prêt pour la production, mais plutôt une explication simple des bases pour résoudre la question à portée de main. Aka, il est très facile de déterminer si un nombre est positif ou négatif et d'ajouter le signe approprié si nécessaire, donc je ne voulais pas regrouper mon exemple facile avec cela. En outre, il est tout aussi facile de créer une fonction prenant une longueur de chiffre comme argument et utilisant cela à la place de mes valeurs codées en dur.
Seaux

5
@Seaux, vous avez dit: " Je ne peux pas croire toutes les réponses complexes" , puis vous avez commencé à vous expliquer la complexité lorsque vous avez commenté. Cela signifie que vous comprenez qu'il existe des perspectives à partir desquelles votre réponse n'est pas parfaite. D'où la complexité.
Om Shankar

2
@OmShankar par "réponses complexes", je ne faisais pas référence à des réponses expliquées ou détaillées (qui sont évidemment encouragées sur ce site même si ma réponse ne l'est pas), mais plutôt à des réponses qui contenaient une complexité de code inutile.
Seaux

7
J'aime cette réponse. Dans mon cas spécifique, je sais que les nombres sont toujours positifs et ne dépassent jamais 3 chiffres, et c'est souvent le cas lorsque vous remplissez avec des 0 en tête et que votre entrée est bien connue. Agréable!
Patrick Chu

110

En fait, j'ai dû trouver quelque chose comme ça récemment. J'ai pensé qu'il devait y avoir un moyen de le faire sans utiliser de boucles.

C'est ce que j'ai trouvé.

function zeroPad(num, numZeros) {
    var n = Math.abs(num);
    var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( num < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

Ensuite, utilisez-le simplement en fournissant un nombre à zéro:

> zeroPad(50,4);
"0050"

Si le nombre est supérieur au remplissage, le nombre s'étendra au-delà du remplissage:

> zeroPad(51234, 3);
"51234"

Les décimales sont bien aussi!

> zeroPad(51.1234, 4);
"0051.1234"

Si cela ne vous dérange pas de polluer l'espace de noms global, vous pouvez l'ajouter directement à Number:

Number.prototype.leftZeroPad = function(numZeros) {
    var n = Math.abs(this);
    var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( this < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

Et si vous préférez que les décimales occupent de l'espace dans le rembourrage:

Number.prototype.leftZeroPad = function(numZeros) {
    var n = Math.abs(this);
    var zeros = Math.max(0, numZeros - n.toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( this < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

À votre santé!



XDR a proposé une variation logarithmique qui semble mieux fonctionner.

AVERTISSEMENT : cette fonction échoue si num est égal à zéro (par exemple zeropad (0, 2))

function zeroPad (num, numZeros) {
    var an = Math.abs (num);
    var digitCount = 1 + Math.floor (Math.log (an) / Math.LN10);
    if (digitCount >= numZeros) {
        return num;
    }
    var zeroString = Math.pow (10, numZeros - digitCount).toString ().substr (1);
    return num < 0 ? '-' + zeroString + an : zeroString + an;
}

En parlant de performance, tomsmeding a comparé les 3 premières réponses ( 4 avec la variation du journal ). Devinez lequel a largement surpassé les deux autres? :)


9
C'est bien, j'aime sa lisibilité et sa robustesse. La seule chose que je changerais est le nom du numZerosparamètre, car il est trompeur. Ce n'est pas le nombre de zéros que vous voulez ajouter, c'est la longueur minimale du nombre. Un meilleur nom serait numLengthou même length.
Senseful

13
+1. Contrairement aux réponses les plus votées, celle-ci gère les nombres négatifs et ne renvoie pas d'erreurs grossières en cas de dépassement !!?!
Brock Adams

10
Mesure des performances parmi les trois principales réponses ici: jsperf.com/left-zero-pad
tomsmeding

4
J'ai amélioré les performances de cette réponse de plus de 100% en utilisant des logarithmes. Veuillez consulter le cas de test logarithmique sur http://jsperf.com/left-zero-pad/10
XDR

2
La solution originale est meilleure, la variation logarithmique ne fonctionne pas si elle numpeut être nulle ...
Ondra C.

69

Voici ce que j'avais l'habitude de remplir jusqu'à 7 caractères.

("0000000" + number).slice(-7)

Cette approche suffira probablement à la plupart des gens.

Edit: Si vous voulez le rendre plus générique, vous pouvez le faire:

("0".repeat(padding) + number).slice(-padding)

Edit 2: Notez que depuis ES2017, vous pouvez utiliser String.prototype.padStart:

number.toString().padStart(padding, "0")

Cela échoue, mal, sur les grands nombres et les nombres négatifs. number = 123456789, avec le code ci-dessus, par exemple.
Brock Adams

Cette solution est la meilleure jamais réalisée pour certains scénarios! Je n'ai aucune idée pourquoi nous n'avons pas trouvé ça avant. Le scénario est le suivant: vous avez un nombre qui est toujours positif [comme l'a mentionné Brock] et vous savez qu'il ne prendra pas plus de caractères que votre limite. Dans notre cas, nous avons un score que nous stockons dans Amazon SDB. Comme vous le savez, SDB ne peut pas comparer les nombres, donc tous les scores doivent être complétés par zéro. C'est extrêmement simple et efficace!
Krystian

4
Toutes mes excuses, j'aurais dû mentionner que cela ne fonctionnera pas pour les nombres négatifs. Je pense que cela concerne le cas du nombre positif le plus courant. Il fait ce dont j'ai besoin, au moins!
chetbox

J'en avais encore besoin et j'ai réalisé que vous n'en aviez pas besoin new String. Vous pouvez simplement utiliser des littéraux de chaîne.
chetbox

3
(new Array(padding + 1).join("0")peut être remplacé par"0".repeat(padding)
Pavel

34

Les navigateurs modernes prennent désormais en charge padStart, vous pouvez simplement faire maintenant:

string.padStart(maxLength, "0");

Exemple:

string = "14";
maxLength = 5; // maxLength is the max string length, not max # of fills
res = string.padStart(maxLength, "0");
console.log(res); // prints "00014"


@Flimm n'hésitez pas à modifier cela dans la réponse :) Il a été écrit il y a 4 ans, donc je suis sûr que les choses ont changé maintenant
Sterling Archer

27

Malheureusement, il y a beaucoup de suggestions compliquées inutiles pour ce problème, impliquant généralement l'écriture de votre propre fonction pour faire des mathématiques ou une manipulation de chaînes ou appeler un utilitaire tiers. Cependant, il existe un moyen standard de le faire dans la bibliothèque JavaScript de base avec une seule ligne de code. Il peut être utile d'envelopper cette seule ligne de code dans une fonction pour éviter d'avoir à spécifier des paramètres que vous ne souhaitez jamais modifier, comme le nom ou le style local.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumIntegerDigits: 3,
    useGrouping: false
});

Cela produira la valeur de "005" pour le texte. Vous pouvez également utiliser la fonction toLocaleString de Number pour ajouter des zéros à droite du séparateur décimal.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumFractionDigits: 2,
    useGrouping: false
});

Cela produira la valeur de "5,00" pour le texte. Remplacez useGrouping par true pour utiliser des séparateurs de virgules pour des milliers.

Notez que l'utilisation toLocaleString()de localeset des optionsarguments est normalisée séparément dans ECMA-402 , pas dans ECMAScript. À ce jour, certains navigateurs n'implémentent que le support de base , c'est toLocaleString()-à- dire peuvent ignorer tous les arguments.

Exemple complet


Wow, c'est une solution super propre et fonctionne dans node.js.
jishi

J'ai gloussé quand j'ai lu l'intro - "suggestions compliquées inutiles". Le développement de logiciels, comme dans toutes les disciplines d'ingénierie, implique de peser les compromis. J'ai moi-même essayé cette «méthode standard» - et je l'ai chronométré. Cela fonctionne certainement, mais je ne choisirais jamais de l'utiliser pour tout type d'application répétitive en raison de sa lenteur par rapport à la plupart des autres solutions "maison".
bearvarine

1
Certes, de nombreuses fonctions JavaScript intégrées fonctionnent mal lors du bouclage sur de nombreuses données, mais je dirais que vous ne devriez pas utiliser JavaScript pour cela, même côté serveur comme Node.js. Si vous avez beaucoup de données à traiter côté serveur, vous devez utiliser une meilleure plate-forme comme .NET ou Java. Si vous traitez des données côté client pour les afficher à l'utilisateur final, vous ne devez traiter les données que pour ce que vous effectuez actuellement sur l'écran de l'utilisateur final. Par exemple, restituez uniquement les lignes visibles d'une table et ne traitez pas les données des autres routes.
Daniel Barbalace

21

Si le nombre de remplissage est connu à l'avance pour ne pas dépasser une certaine valeur, il existe une autre façon de le faire sans boucles:

var fillZeroes = "00000000000000000000";  // max number of zero fill ever asked for in global

function zeroFill(number, width) {
    // make sure it's a string
    var input = number + "";  
    var prefix = "";
    if (input.charAt(0) === '-') {
        prefix = "-";
        input = input.slice(1);
        --width;
    }
    var fillAmt = Math.max(width - input.length, 0);
    return prefix + fillZeroes.slice(0, fillAmt) + input;
}

Cas de test ici: http://jsfiddle.net/jfriend00/N87mZ/


@BrockAdams - corrigé pour les deux cas que vous mentionnez. Si le nombre est déjà aussi large que la largeur de remplissage, aucun remplissage n'est ajouté.
jfriend00

Merci; +1. Les chiffres négatifs sont cependant légèrement différents de la convention habituelle. Dans votre cas de test, -88devrait céder "-00088", par exemple.
Brock Adams

1
@BrockAdams - Je ne savais pas si l'appel zeroFill(-88, 5)devrait produire -00088ou -0088? Je suppose que cela dépend si vous voulez que l' widthargument soit la largeur entière du nombre ou juste le nombre de chiffres (sans compter le signe négatif). Un implémenteur peut facilement changer le comportement pour ne pas inclure le signe négatif en supprimant simplement la --widthligne de code.
jfriend00

19

La manière rapide et sale:

y = (new Array(count + 1 - x.toString().length)).join('0') + x;

Pour x = 5 et count = 6, vous aurez y = "000005"


1
J'ai obtenu y="0005"avec ce qui précède, y = (new Array(count + 1 - x.toString().length)).join('0') + x;c'est ce qui m'a donnéy="000005"
forforf

3
@OrrSiloni: la solution de code la plus courte est en fait('0000'+n).slice(-4)
Seaux

14

Voici une fonction rapide que j'ai trouvée pour faire le travail. Si quelqu'un a une approche plus simple, n'hésitez pas à partager!

function zerofill(number, length) {
    // Setup
    var result = number.toString();
    var pad = length - result.length;

    while(pad > 0) {
        result = '0' + result;
        pad--;
    }

    return result;
}

Je ne pense pas qu'il y aura une solution "plus simple" - ce sera toujours une fonction quelconque. Nous pourrions avoir une discussion sur l'algorithme, mais à la fin de la journée, vous vous retrouverez toujours avec une fonction qui remplit un nombre.
Peter Bailey

Mon conseil général est d'utiliser les boucles "for" car elles sont généralement plus stables et plus rapides dans les langages ECMAScript (ActionScript 1-3 et JavaScript)
cwallenpoole

Ou, ignorez complètement l'itération;)
Peter Bailey

Fonction plus simple? Probablement pas. Celui qui ne boucle pas? C'est possible ... bien que l'algorithme ne soit pas tout à fait trivial.
coderjoe

1
Wow, à peu près tous les commentaires ci-dessus sont incorrects. La solution de @ profitehlolz est plus simple et adaptée à l'inline (n'a pas besoin d'être une fonction). Pendant ce temps, for.vs. whileles performances ne sont pas assez différentes pour être intéressantes: jsperf.com/fors-vs- while
34

12

Tard dans la fête ici, mais j'utilise souvent cette construction pour faire un remplissage ad hoc d'une certaine valeur n, connue pour être une décimale positive:

(offset + n + '').substr(1);

offsetest 10 ^^ chiffres.

Par exemple, remplissage à 5 chiffres, où n = 123:

(1e5 + 123 + '').substr(1); // => 00123

La version hexidécimale de ceci est légèrement plus détaillée:

(0x100000 + 0x123).toString(16).substr(1); // => 00123

Note 1: J'aime aussi la solution de @ profitehlolz, qui est la version chaîne de ceci, utilisant la fonctionnalité astucieuse d'index négatif de slice ().


12

Je ne sais vraiment pas pourquoi, mais personne ne l'a fait de la manière la plus évidente. Voici mon implémentation.

Une fonction:

/** Pad a number with 0 on the left */
function zeroPad(number, digits) {
    var num = number+"";
    while(num.length < digits){
        num='0'+num;
    }
    return num;
}

Prototype:

Number.prototype.zeroPad=function(digits){
    var num=this+"";
    while(num.length < digits){
        num='0'+num;
    }
    return(num);
};

Très simple, je ne vois pas comment cela peut être plus simple. Pour une raison quelconque, il me semble que plusieurs fois ici sur SO, les gens essaient juste d'éviter les boucles "pour" et "tandis que" à tout prix. L'utilisation de regex coûtera probablement beaucoup plus de cycles pour un remplissage aussi simple à 8 chiffres.


11

J'utilise ce snipet pour obtenir une représentation à 5 chiffres

(value+100000).toString().slice(-5) // "00123" with value=123


9

Le pouvoir des mathématiques!

x = entier à remplir
y = nombre de zéros à remplir

function zeroPad(x, y)
{
   y = Math.max(y-1,0);
   var n = (x / Math.pow(10,y)).toFixed(y);
   return n.replace('.','');  
}

9

Je n'ai vu personne souligner le fait que lorsque vous utilisez String.prototype.substr () avec un nombre négatif, il compte à droite.

Une solution à une réponse à la question du PO, une représentation à 6 chiffres remplie de zéros du nombre 5, est:

console.log(("00000000" + 5).substr(-6));

En généralisant, nous obtiendrons:

function pad(num, len) { return ("00000000" + num).substr(-len) };

console.log(pad(5, 6));
console.log(pad(45, 6));
console.log(pad(345, 6));
console.log(pad(2345, 6));
console.log(pad(12345, 6));


8

Après un long, très long test de 15 fonctions / méthodes différentes trouvées dans les réponses à ces questions, je sais maintenant laquelle est la meilleure (la plus polyvalente et la plus rapide).

J'ai pris 15 fonctions / méthodes à partir des réponses à cette question et fait un script pour mesurer le temps nécessaire pour exécuter 100 pads. Chaque pavé remplirait le nombre 9de 2000zéros. Cela peut sembler excessif, et c'est le cas, mais cela vous donne une bonne idée de la mise à l'échelle des fonctions.

Le code que j'ai utilisé se trouve ici: https://gist.github.com/NextToNothing/6325915

N'hésitez pas à modifier et tester le code vous-même.

Afin d'obtenir la méthode la plus polyvalente, vous devez utiliser une boucle. En effet, avec un très grand nombre, d'autres sont susceptibles d'échouer, alors que cela réussira.

Alors, quelle boucle utiliser? Eh bien, ce serait une whileboucle. Une forboucle est toujours rapide, mais une whileboucle est juste un peu plus rapide (quelques ms) - et plus propre.

Des réponses comme celles de Wilco, Aleksandar Toplekou Vitim.usferont parfaitement l'affaire.

Personnellement, j'ai essayé une approche différente. J'ai essayé d'utiliser une fonction récursive pour remplir la chaîne / le nombre. Cela fonctionnait mieux que les méthodes joignant un tableau mais, toujours, ne fonctionnait pas aussi rapidement qu'une boucle for.

Ma fonction est:

function pad(str, max, padder) {
  padder = typeof padder === "undefined" ? "0" : padder;
  return str.toString().length < max ? pad(padder.toString() + str, max, padder) : str;
}

Vous pouvez utiliser ma fonction avec ou sans définir la variable de remplissage. Alors comme ça:

pad(1, 3); // Returns '001'
// - Or -
pad(1, 3, "x"); // Returns 'xx1'

Personnellement, après mes tests, j'utiliserais une méthode avec une boucle while, comme Aleksandar Toplekou Vitim.us. Cependant, je le modifierais légèrement pour que vous puissiez définir la chaîne de remplissage.

Donc, j'utiliserais ce code:

function padLeft(str, len, pad) {
    pad = typeof pad === "undefined" ? "0" : pad + "";
    str = str + "";
    while(str.length < len) {
        str = pad + str;
    }
    return str;
}

// Usage
padLeft(1, 3); // Returns '001'
// - Or -
padLeft(1, 3, "x"); // Returns 'xx1'

Vous pouvez également l'utiliser comme fonction prototype, en utilisant ce code:

Number.prototype.padLeft = function(len, pad) {
    pad = typeof pad === "undefined" ? "0" : pad + "";
    var str = this + "";
    while(str.length < len) {
        str = pad + str;
    }
    return str;
}

// Usage
var num = 1;

num.padLeft(3); // Returns '001'
// - Or -
num.padLeft(3, "x"); // Returns 'xx1'

Je l'ai mis dans un jsfiddle pour que les autres puissent le tester rapidement, en ajoutant votre version du code: jsfiddle.net/kevinmicke/vnvghw7y/2 Votre version est toujours très compétitive, et parfois la plus rapide. Merci pour les tests assez exhaustifs.
kevinmicke

8

Le premier paramètre est un nombre réel, le deuxième paramètre est un entier positif spécifiant le nombre minimum de chiffres à gauche de la virgule décimale et le troisième paramètre est un entier positif facultatif spécifiant le nombre si les chiffres se trouvent à droite de la virgule décimale.

function zPad(n, l, r){
    return(a=String(n).match(/(^-?)(\d*)\.?(\d*)/))?a[1]+(Array(l).join(0)+a[2]).slice(-Math.max(l,a[2].length))+('undefined'!==typeof r?(0<r?'.':'')+(a[3]+Array(r+1).join(0)).slice(0,r):a[3]?'.'+a[3]:''):0
}

donc

           zPad(6, 2) === '06'
          zPad(-6, 2) === '-06'
       zPad(600.2, 2) === '600.2'
        zPad(-600, 2) === '-600'
         zPad(6.2, 3) === '006.2'
        zPad(-6.2, 3) === '-006.2'
      zPad(6.2, 3, 0) === '006'
        zPad(6, 2, 3) === '06.000'
    zPad(600.2, 2, 3) === '600.200'
zPad(-600.1499, 2, 3) === '-600.149'


8

Ceci est la solution ES6.

function pad(num, len) {
  return '0'.repeat(len - num.toString().length) + num;
}
alert(pad(1234,6));


De toute évidence, la solution la plus élégante que je voudrais juste modifier pour éviter les conversions de 2 chaînes: const numStr = String(num)etreturn '0'.repeat(len - numStr.length) + numStr;
ngryman

8

Dans tous les navigateurs modernes, vous pouvez utiliser

numberStr.padStart(numberLength, "0");

function zeroFill(num, numLength) {
  var numberStr = num.toString();

  return numberStr.padStart(numLength, "0");
}

var numbers = [0, 1, 12, 123, 1234, 12345];

numbers.forEach(
  function(num) {
    var numString = num.toString();
    
    var paddedNum = zeroFill(numString, 5);

    console.log(paddedNum);
  }
);

Voici la référence MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart


5

Non pas que cette question nécessite plus de réponses, mais j'ai pensé que j'ajouterais la version lodash simple de cela.

_.padLeft(number, 6, '0')


1
Mieux:var zfill = _.partialRight(_.padStart, '0');
Droogans

3
Certaines personnes protesteront probablement "Je ne veux pas utiliser lodash" mais ce n'est plus un argument valable car vous ne pouvez installer que cette fonction:, npm install --save lodash.padleftpuis import padLeft from 'lodash.padleft'et omettre le_.
Andy

5

La dernière façon de le faire est beaucoup plus simple:

var number = 2
number.toLocaleString(undefined, {minimumIntegerDigits:2})

output: "02"


(8).toLocaleString(undefined, {minimumIntegerDigits: 5})revient "00.008"pour moi, en fonction de mes paramètres régionaux.
le_m


4

Celui-ci est moins natif, mais peut-être le plus rapide ...

zeroPad = function (num, count) {
    var pad = (num + '').length - count;
    while(--pad > -1) {
        num = '0' + num;
    }
    return num;
};

je pense que tu veux faire pad = count - (num + '').length. les nombres négatifs ne sont pas bien gérés, mais à part cela, ce n'est pas mauvais. +1
nickf

3

Ma solution

Number.prototype.PadLeft = function (length, digit) {
    var str = '' + this;
    while (str.length < length) {
        str = (digit || '0') + str;
    }
    return str;
};

Usage

var a = 567.25;
a.PadLeft(10); // 0000567.25

var b = 567.25;
b.PadLeft(20, '2'); // 22222222222222567.25

3

Pourquoi ne pas utiliser la récursivité?

function padZero(s, n) {
    s = s.toString(); // in case someone passes a number
    return s.length >= n ? s : padZero('0' + s, n);
}

padZero (223, 3) échoue avec '0223'
Serginho

Eh bien, j'ai supposé que cette fonction est appelée avec une chaîne comme premier paramètre. Cependant, je l'ai corrigé.
lex82

2

Certains monkeypatching fonctionnent également

String.prototype.padLeft = function (n, c) {
  if (isNaN(n))
    return null;
  c = c || "0";
  return (new Array(n).join(c).substring(0, this.length-n)) + this; 
};
var paddedValue = "123".padLeft(6); // returns "000123"
var otherPadded = "TEXT".padLeft(8, " "); // returns "    TEXT"

1
-1 monkeypatching l'espace de noms de niveau supérieur en javascript est une mauvaise pratique.
Jeremy Wall

2
Vrai pour les objets Object et Array, mais String n'est pas mauvais
Rodrigo

2
function pad(toPad, padChar, length){
    return (String(toPad).length < length)
        ? new Array(length - String(toPad).length + 1).join(padChar) + String(toPad)
        : toPad;
}

pad(5, 0, 6) = 000005

pad('10', 0, 2) = 10 // don't pad if not necessary

pad('S', 'O', 2) = SO

...etc.

À votre santé


Je pense que cela devrait plutôt ressembler à ceci: var s = String(toPad); return (s.length < length) ? new Array(length - s.length + 1).join('0') + s : s;si vous le corrigez, je retirerai mon vote négatif.
drewish

@drewish Merci d'avoir attrapé cela, je suis d'accord avec votre modification (à l'exception du caractère de 0jointure codé en dur :) - Réponse mise à jour.
Madbreaks

Je pense qu'il serait préférable de stocker la chaîne dans une variable temporaire. J'ai fait une analyse comparative de cela ici: jsperf.com/padding-with-memoization, il a également des repères pour l'utilisation du nouveau dans "new Array", les résultats pour new sont partout, mais la mémiozation semble être la voie à suivre.
drewish

2

La solution la plus simple et la plus simple que vous trouverez.

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}
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.