Pergunta

Qual é a maneira recomendada de zero um valor em JavaScript? Imagino que eu poderia construir uma função personalizada para adotar zeros em um valor tipulado, mas estou me perguntando se há uma maneira mais direta de fazer isso?

Observação: Por "Zerofille", quero dizer isso no sentido do banco de dados da palavra (onde uma representação zerois de 6 dígitos do número 5 seria "000005").

Foi útil?

Solução

Nota para os leitores!

Como os comentaristas apontaram, essa solução é "inteligente" e, como as soluções inteligentes geralmente são, é intensiva em memória e relativamente lenta. Se o desempenho é uma preocupação para você, não use esta solução!

Potencialmente desatualizado: ECMAScript 2017 inclui String.prototype.padstart e Número.prototype.tolocalestring existe desde o ECMAScript 3.1. Exemplo:

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

... será a saída "-0000.10".

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

... será a saída "-0000.1".

Uma função 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ê pode assar isso em uma biblioteca se quiser economizar namespace ou qualquer outra coisa. Como em JQuery's estende.

Outras dicas

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

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

Como uma função,

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 isso:

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

Na verdade, tive que inventar algo assim recentemente. Imaginei que tinha que haver uma maneira de fazê -lo sem usar loops.

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

Em seguida, basta usá -lo, fornecendo um número para zero pad:

> zeroPad(50,4);
"0050"

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

> zeroPad(51234, 3);
"51234"

Decimais também estão bem!

> zeroPad(51.1234, 4);
"0051.1234"

Se você não se importa de poluir o espaço para nome global, poderá adicioná -lo diretamente:

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 uma variação logarítmica Isso parece ter um desempenho melhor.

AVISO: Esta função falha se o número for igual a zero (por exemplo, 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, tomseding comparou as 3 principais respostas (4 com a variação do log). Adivinhe qual principalmente superou os outros dois? :)

Aqui está o que eu costumava fazer com um número de até 7 caracteres.

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

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

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

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

EDIT 2: Observe que desde o ES2017 você pode usar String.prototype.padStart:

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

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

var amount = 5;

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

Isso produzirá o valor de "005" para texto. Você também pode usar a função tolocalestradora do número para fazer zeros para o 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 texto. Altere o uso de uso para true para usar separadores de vírgula por milhares.

Observe isso usando toLocaleString() com locales e options argumentos é padronizado separadamente na ECMA-402, não no ecmascript. A partir de hoje, alguns navegadores Implementar apenas suporte básico, ou seja toLocaleString() pode ignorar quaisquer argumentos.

Exemplo completo

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

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/

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

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

A maneira rápida e suja:

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

Para x = 5 e contagem = 6 você terá y = "000005"

Aqui está uma função rápida que eu inventei para fazer o trabalho. Se alguém tiver uma abordagem mais simples, fique à 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 muitas vezes uso esse construto para fazer 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 para 5 dígitos, onde n = 123:

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

A versão hexidecimal 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 recurso de índice negativo de Slice ().

Eu realmente não sei por que, 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, então as pessoas apenas tentam evitar 'para' e 'enquanto' loops a qualquer custo. O uso do Regex provavelmente custará muito mais ciclos para um preenchimento tão trivial 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 = número 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('.','');  
}

Ecmascript 2017: Use padstart ou padend

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

Mais informações:

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

Uma solução de um revestimento para a pergunta do OP, uma representação zero infectada de 6 dígitos do número 5, é:

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

Generalizando vamos obter:

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

O primeiro parâmetro é qualquer número real, o segundo parâmetro é um número inteiro positivo que especifica o número mínimo de dígitos à esquerda do ponto decimal e o terceiro parâmetro é um número inteiro positivo opcional que especifica o número se dígitos à direita do ponto 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<r?'.':'')+(a[3]+Array(r+1).join(0)).slice(0,r):a[3]?'.'+a[3]:''):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'

Não reinvente a roda, use String sublinhada:

jsfiddle

var numToPad = '5';

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

Esta é a solução ES6.

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

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

Peguei 15 funções/métodos das respostas a esta pergunta e fiz um script para medir o tempo necessário para executar 100 almofadas. Cada almofada faria o número 9 com 2000 zeros. Isso pode parecer excessivo, e é, mas oferece uma boa idéia sobre a escala 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 sozinho.

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

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

Respostas como essas por Wilco, Aleksandar Toplek ou Vitim.us fará o trabalho perfeitamente.

Pessoalmente, tentei uma abordagem diferente. Tentei usar uma função recursiva para encaixar a string/número. Funcionou melhor do que os métodos que ingressam em uma matriz, mas, ainda assim, não funcionou tão rápido quanto um loop for.

Minha função é:

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 função ou sem, definindo a 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 de tempo, como Aleksandar Toplek ou Vitim.us. No entanto, eu o modificaria um pouco para poder definir a sequência de preenchimento.

Então, eu usaria este 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 função de 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'

Em todos os navegadores modernos que 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);
  }
);

Aqui está a referência do MDN https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/string/padstart

Não que essa pergunta precise de mais respostas, mas pensei em adicionar a versão simples do Lodash disso.

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

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

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

output: "02"

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

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

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

Por que não usar a recursão?

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

Alguns macacos também funcionam

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

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

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top