Como posso preencher um valor com zeros à esquerda?

Qual é a maneira recomendada de preencher um valor em JavaScript? Eu imagino que eu poderia construir uma function personalizada para preencher zeros em um valor typecasted, mas eu estou querendo saber se existe uma maneira mais direta de fazer isso?

Nota: Por “zerofilled” quero dizer no sentido do database da palavra (onde uma representação zerofilled de 6 dígitos do número 5 seria “000005”).

Nota para os leitores!

Como observadores comentaram, essa solução é “inteligente” e, como as soluções inteligentes costumam ser, a memory é intensiva e relativamente lenta. Se o desempenho é uma preocupação para você, não use essa solução!

Potencialmente desatualizado : o ECMAScript 2017 inclui o String.prototype.padStart e o Number.prototype.toLocaleString , desde o ECMAScript 3.1. Exemplo:

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

… irá gerar “-0000.10”.

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

… irá imprimir “-0000.1”.

Uma function simples é tudo que você precisa

 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 } 

você poderia fazer isso em uma biblioteca se quiser economizar espaço de nomes ou qualquer outra coisa. Como com o extenso do jQuery .

Maneira simples. Você pode adicionar multiplicação de string para o pad e transformá-lo em uma function.

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

Como uma function,

 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 

Eu não posso acreditar em todas as respostas complexas aqui … apenas use isto:

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

Eu realmente tive que pensar em algo assim recentemente. Eu percebi que tinha que haver uma maneira de fazer isso sem usar loops.

Isso é o que eu criei.

 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; } 

Então é só usá-lo fornecendo um número para zerar pad:

 > zeroPad(50,4); "0050" 

Se o número for maior que o preenchimento, o número será expandido além do preenchimento:

 > zeroPad(51234, 3); "51234" 

Decimais estão bem também!

 > zeroPad(51.1234, 4); "0051.1234" 

Se você não se importa de poluir o namespace global, você pode adicioná-lo diretamente ao 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; } 

E se você preferir que os decimais ocupem espaço no preenchimento:

 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; } 

Felicidades!



XDR surgiu com uma variação logarítmica que parece ter um melhor desempenho.

ATENÇÃO : Esta function falha se num for igual a zero (ex. 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; } 

Falando em desempenho, o tomsmeding comparou as 3 principais respostas ( 4 com a variação do log ). Adivinha qual deles superou principalmente os outros dois? 🙂

Aqui está o que eu usei para preencher um número de até 7 caracteres.

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

Essa abordagem provavelmente será suficiente para a maioria das pessoas.

Edit: Se você quiser torná-lo mais genérico, você pode fazer isso:

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

Infelizmente, há muitas sugestões desnecessárias e complicadas para esse problema, geralmente envolvendo a criação de sua própria function para manipular matemática ou string ou chamar um utilitário de terceiros. No entanto, existe uma maneira padrão de fazer isso na biblioteca JavaScript de base com apenas uma linha de código. Pode valer a pena envolver essa linha de código em uma function para evitar a necessidade de especificar parâmetros que você nunca deseja alterar, como o nome ou o estilo local.

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

Isso produzirá o valor de “005” para o texto. Você também pode usar a function toLocaleString de Number para preencher zeros no lado direito do ponto decimal.

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

Isso produzirá o valor de “5,00” para o texto. Altere useGrouping para true para usar separadores de vírgulas para milhares.

Observe que o uso de toLocaleString() com argumentos de locales e options é padronizado separadamente no ECMA-402 , não no ECMAScript. A partir de hoje, alguns navegadores implementam apenas suporte básico , ou seja, toLocaleString() pode ignorar qualquer argumento.

Exemplo Completo

Se o número de preenchimento for conhecido antecipadamente para não exceder um determinado valor, existe outra maneira de fazer isso sem fazer um loop:

 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; } 

Casos de teste aqui: http://jsfiddle.net/jfriend00/N87mZ/

A maneira rápida e suja:

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

Para x = 5 e count = 6 você terá y = “000005”

Em um método .padStart() proposto (estágio 3) .padStart .padStart() você pode simplesmente fazer (quando implementado / suportado):

 string.padStart(maxLength, "0"); //max length is the max string length, not max # of fills 

Aqui está uma function rápida que eu criei para fazer o trabalho. Se alguém tiver uma abordagem mais simples, sinta-se à vontade para compartilhar!

 function zerofill(number, length) { // Setup var result = number.toString(); var pad = length - result.length; while(pad > 0) { result = '0' + result; pad--; } return result; } 

Tarde para a festa aqui, mas eu costumo usar essa construção para fazer o preenchimento ad-hoc de algum valor n , conhecido por ser um decimal positivo:

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

Onde offset é 10 ^^ dígitos.

Por exemplo, preenchimento com 5 dígitos, em que n = 123:

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

A versão hexadecimal disso é um pouco mais detalhada:

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

Nota 1: Eu também gosto da solução do profitehlolz, que é a versão de string disso, usando o interessante recurso de índice negativo do slice ().

Eu realmente não sei porque, mas ninguém fez isso da maneira mais óbvia. Aqui está minha implementação.

Função:

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

Protótipo:

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

Muito simples, não consigo ver como isso pode ser mais simples. Por alguma razão eu pareço muitas vezes aqui no SO, as pessoas tentam evitar loops 'for' e 'while' a qualquer custo. Usar o regex provavelmente custará muito mais ciclos para um preenchimento tão simples de 8 dígitos.

Eu uso este snipet para obter uma representação de 5 dígitos

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

O poder da matemática!

x = inteiro para pad
y = número de zeros para pad

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

Não reinvente a roda, use a string de sublinhado :

jsFiddle

 var numToPad = '5'; alert(_.str.pad(numToPad, 6, '0')); // yields: '000005' 

Esta é a solução do ES6.

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

Após um longo, longo tempo de teste de 15 diferentes funções / methods encontrados nas perguntas, agora sei qual é o melhor (o mais versátil e mais rápido).

Eu peguei 15 funções / methods das respostas a essa pergunta e fiz um script para medir o tempo gasto para executar 100 pads. Cada pad preencheria o número 9 com 2000 zeros. Isso pode parecer excessivo, e é, mas dá uma boa idéia sobre o dimensionamento das funções.

O código que usei pode ser encontrado aqui: https://gist.github.com/NextToNothing/6325915

Sinta-se à vontade para modificar e testar o código.

Para obter o método mais versátil, você precisa usar um loop. Isso ocorre porque, com números muito grandes, outros provavelmente falharão, ao passo que isso será bem-sucedido.

Então, qual loop usar? Bem, isso seria um loop while. Um loop for ainda é rápido, mas um loop while é apenas um pouco mais rápido (um par de ms) – e mais limpo.

Respostas como as de Wilco , Aleksandar Toplek ou Vitim.us farão o trabalho perfeitamente.

Pessoalmente, tentei uma abordagem diferente. Eu tentei usar uma function recursiva para preencher a string / número. Ele funcionou melhor do que os methods que se juntaram a um array, mas, ainda assim, não funcionou tão rápido quanto um loop for.

Minha function é:

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

Você pode usar minha function com ou sem a configuração da variável de preenchimento. Então, assim:

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

Pessoalmente, após meus testes, eu usaria um método com um loop while, como Aleksandar Toplek ou Vitim.us . No entanto, eu iria modificá-lo um pouco para que você possa definir a string de preenchimento.

Então, eu usaria esse código:

 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' 

Você também pode usá-lo como uma function protótipo, usando este código:

 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' 

Primeiro parâmetro é qualquer número real, segundo parâmetro é um inteiro positivo especificando o número mínimo de dígitos à esquerda da vírgula decimal e terceiro parâmetro é um inteiro positivo opcional especificando o número se dígitos à direita da vírgula decimal.

 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 

assim

  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' 

ECMAScript 2017: use padStart ou padEnd

 'abc'.padStart(10); // " abc" 'abc'.padStart(10, "foo"); // "foofoofabc" 'abc'.padStart(6,"123465"); // "123abc" 

Mais informações:

Eu não vi ninguém apontar o fato de que quando você usa String.prototype.substr () com um número negativo, ele conta a partir da direita.

Uma solução de um liner para a questão do OP, uma representação zerofilled de 6 dígitos do número 5, é:

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

A última maneira de fazer isso é muito mais simples:

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

output: "02"

Em todos os navegadores modernos você pode usar

 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); } ); 

Este é menos nativo, mas pode ser o mais rápido …

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

Minha solução

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

Uso

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

Não que esta questão precise de mais respostas, mas eu pensei em acrescentar a versão lodash simples disso.

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

Apenas uma outra solução, mas acho que é mais legível.

 function zeroFill(text, size) { while (text.length < size){ text = "0" + text; } return text; } 

Por que não usar recursion?

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

Alguns monkeypatching também funciona

 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" 
 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

Felicidades

A solução mais simples e direta que você encontrará.

 function zerofill(number,length) { var output = number.toString(); while(output.length < length) { output = '0' + output; } return output; }