Como imprimir um número com vírgulas como separadores de milhares em JavaScript


1783

Estou tentando imprimir um número inteiro em JavaScript com vírgulas como separadores de milhares. Por exemplo, quero mostrar o número 1234567 como "1.234.567". Como eu faria isso?

Aqui está como eu estou fazendo isso:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

Existe uma maneira mais simples ou mais elegante de fazer isso? Seria bom se ele trabalha com carros alegóricos também, mas isso não é necessário. Não precisa ser específico do local para decidir entre pontos e vírgulas.


156
Número (x) .toLocaleString ()
Boffin

@Boffin isso não está funcionando para o número de tipo de entrada (por causa de vírgulas) - em resposta aceita podemos substituir vírgula para ponto e número tipo de entrada vai funcionar
Vitaly Zdanevich

48
Vale ressaltar que Number.prototype.toLocaleString ainda não funciona no Safari, em 2016 . Em vez de realmente formatar o número, ele apenas retorna, sem erro. Tendo a maior facepalm hoje como um resultado de que ... #goodworkApple
aendrew

No entanto, parece funcionar no safari do iOS.
Tim

toLocaleString é inconsistente e não deve ser usado. Por exemplo - no Firefox, isso retornará 1.234, mas no IE, isso adicionará decimais: 1.234,00
Bort

Respostas:


2836

Usei a ideia da resposta de Kerry, mas a simplifiquei, pois estava apenas procurando algo simples para o meu propósito específico. Aqui está o que eu fiz:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}


O regex usa 2 asserções lookahead:

  • positivo para procurar qualquer ponto na sequência que tenha vários 3 dígitos seguidos depois,
  • uma afirmação negativa para garantir que esse ponto tenha apenas exatamente um múltiplo de 3 dígitos. A expressão de substituição coloca uma vírgula lá.

Por exemplo, se você a passar 123456789.01, a afirmação positiva corresponderá a todos os pontos à esquerda dos 7 (já que 789é um múltiplo de 3 dígitos, 678é um múltiplo de 3 dígitos 567, etc.). A asserção negativa verifica se o múltiplo de 3 dígitos não possui nenhum dígito depois dele. 789tem um período depois dele, então é exatamente um múltiplo de 3 dígitos, então uma vírgula vai para lá. 678é um múltiplo de 3 dígitos, mas possui um 9depois, portanto esses 3 dígitos fazem parte de um grupo de 4 e uma vírgula não vai para lá. Da mesma forma para 567. 456789tem 6 dígitos, que é um múltiplo de 3, então uma vírgula é anterior a isso. 345678é um múltiplo de 3, mas tem um 9depois, portanto, nenhuma vírgula vai para lá. E assim por diante. o\B impede que o regex coloque vírgula no início da string.

@ neu-rah mencionou que esta função adiciona vírgulas em locais indesejáveis ​​se houver mais de 3 dígitos após o ponto decimal. Se este for um problema, você pode usar esta função:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

@ tjcrowder apontou que agora que o JavaScript está oculto ( informações de suporte ), ele pode ser resolvido na própria expressão regular:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

(?<!\.\d*)é um aspecto negativo que indica que a correspondência não pode ser precedida por um .seguido por zero ou mais dígitos. O lookbehind negativo é mais rápido que a solução splite join( comparação ), pelo menos na V8.


21
Muito legal, percebeu que há problemas com números que têm mais de 3 casas após o ponto decimal.
Eric Petroelje 23/02

60
tente numberWithCommas (12345.6789) -> "12,345.6,789" eu não gosto
neu-rah

4
Ele não funciona bem com frações, não gostaria de ter vírgulas depois do ponto decimal
Mugen

30
Pequena melhoria que é corrigida após '.' problema '123456789.01234'. substituir (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g, '_')
Dmitrij Golubev

8
@DmitrijGolubev Não funciona para números inteiros. Talvez forçar o ponto decimal seja a solução.
Vlad

1809

Estou surpreso que ninguém tenha mencionado Number.prototype.toLocaleString . Ele foi implementado no JavaScript 1.5 (que foi introduzido em 1999) e, portanto, é basicamente suportado nos principais navegadores.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"

Também funciona no Node.js a partir da v0.12 através da inclusão de Intl

Apenas preste atenção que esta função retorna uma string, não um número.

Se você quiser algo diferente, o Numeral.js pode ser interessante.


17
@csigrist Bons pontos, mas não é tão ruim quanto parece. A velocidade depende do navegador. No FF ou Opera, ele executa bem. Eu sou péssimo no Chrome. Quanto aos zeros: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"essas opções não funcionam no FF ou no Safari.
uKolka

22
A diferença de desempenho pode ou não ser um problema, dependendo do contexto. Se usado para uma tabela gigante de 1.000 resultados, será mais importante, mas se usado apenas por um único valor, a diferença é insignificante. Mas a vantagem é que ele é compatível com a localidade, para que alguém na Europa veja 34.523.453.345 ou 34 523 453.345 . Isso seria mais importante em um site com visitantes de vários países.
T Nguyen

6
Impressionante. Finalmente, uma resposta com função nativa. E mais, este é exibido corretamente em diferentes países com diferentes separadores (na República Tcheca, escrevemos X XXX XXX,YYY).
Tomáš Zato - Restabelecer Monica

22
Atualização para googlers: toLocaleStringfunciona no Node.js a partir da v0.12 por meio da inclusão do Intl .
srobinson

8
@MSC você deve tentar parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})ou new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})não. Não funciona porque você o usa em uma string, não em um número.
22416 uKolka

244
var number = 1234567890; // Example number to be converted

⚠ Lembre-se de que o javascript tem um valor inteiro máximo de 9007199254740991


toLocaleString :

number.toLocaleString(); // "1,234,567,890"

// A more complex example: 
var number2 = 1234.56789; // floating point example
number2.toLocaleString(undefined, {maximumFractionDigits:2}) // "1,234.57"


NumberFormat ( Safari não suportado):

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"

Pelo que verifiquei (Firefox pelo menos), ambos são mais ou menos iguais em relação ao desempenho.


6
NumberFormat não é suportado no Safari, para quem está implementando lá.
Marcovega 12/11/2015

6
toLocaleString também não é suportado em safari
Deepak Banka

3
O suporte a navegadores é sempre mencionado na parte inferior de cada página MDN, à qual eu vinculei.
vsync

5
básicos toLocaleStringobras sobre safari, opções não
dandavis

3
a toLocaleStringsolução provavelmente também deve incluir o local desejado, portanto toLocaleString("en"), porque o padrão em inglês usa vírgulas. No entanto, se o toLocaleString()indicador sem local for executado na França, ele produzirá períodos em vez de vírgulas, porque é isso que é usado para separar milhares localmente.
Mike 'Pomax' Kamermans

112

Sugiro usar o number_format () do phpjs.org

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

ATUALIZAÇÃO 13/02/14

As pessoas têm relatado que isso não funciona como esperado, então eu fiz um JS Fiddle que inclui testes automatizados.

Atualização 26/11/2017

Aqui está o violino como um snippet de pilha com saída levemente modificada:

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
    var actual = number_format(number, decimals, dec_point, thousands_sep);
    console.log(
        'Test case ' + exampleNumber + ': ' +
        '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
        ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
        ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
    );
    console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
    exampleNumber++;
}

test('1,235',    1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57',  1234.5678, 2, '.', '');
test('67,00',    67, 2, ',', '.');
test('1,000',    1000);
test('67.31',    67.311, 2);
test('1,000.6',  1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1',        0.9, 0);
test('1.20',     '1.20', 2);
test('1.2000',   '1.20', 4);
test('1.200',    '1.2000', 3);
.as-console-wrapper {
  max-height: 100% !important;
}


Não que eu o marquei, mas acredito que as pessoas fizeram isso porque não funciona. Tal como está, considero que alguns dos seus testes não funcionam.
Andrew S

3
@ Andrew S - Apenas uma pessoa marcou. Funciona, eu o usei no meu próprio código várias vezes. Também não é meu código (nem meus testes), referenciei o site de origem, que é um site conhecido. Talvez eles tenham uma versão atualizada), pois o código que você está vendo tem 3 anos.
Kerry Jones

13
@ernix - O operador pediu JavaScript, a resposta que dei foi JavaScript. Esta é uma interpretação JavaScript de uma função PHP.
Kerry Jones

2
@ernix - funciona exatamente como esperado com o exemplo que o OP deu. Eu coloquei um violino para que você possa ver.
Kerry Jones

4
@ernix - Ok, mas o ponto é que ele faz exatamente o que o OP pediu. É de outro site (não mantido por mim, e afirmei isso anteriormente) e, ao fornecer variáveis ​​apropriadas, funciona exatamente como indicado. Se você acredita que isso é um bug, entre em contato com phpjs.org ou veja se eles têm uma versão atualizada.
Kerry Jones

75

Esta é uma variação da resposta de @ mikez302, mas modificada para suportar números com decimais (de acordo com o feedback de @ neu-rah que numberWithCommas (12345.6789) -> "12.345.6.789" em vez de "12.345.6789"

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}


67
function formatNumber (num) {
    return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

print(formatNumber(2665));      // 2,665
print(formatNumber(102665));    // 102,665
print(formatNumber(111102665)); // 111,102,665

O que isso faz que minha resposta não faz? O regex parece um pouco diferente, mas parece que deve fazer a mesma coisa.
Elias Zamaria

8
é mais curto :) #
484 Tutankhamen

4
Isso é elegante. Exatamente o que eu estava procurando.
tradicional

4
De blog.tompawlak.org/number-currency-formatting-javascript ? Problema conhecido: formatNumber (0.123456) = 0.123.456 A ausência de lookbehind no JS dificulta a correção com um regex elegante.
Vlad

1
123456789.123456789.toString (). Replace (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1') => 123,456,789.12345679
kenberkeley

53

Usando expressão regular

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

Usando toLocaleString ()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN: Number.prototype.toLocaleString ()

Usando Intl.NumberFormat ()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

ref Intl.NumberFormat

DEMO AQUI

<script type="text/javascript">
  // Using Regular expression
  function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function commas() {
    var num1 = document.myform.number1.value;

    // Using Regular expression
    document.getElementById('result1').value = toCommas(parseInt(num1));
    // Using toLocaleString()

    document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    });

    // Using Intl.NumberFormat()
    document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    }).format(num1);
  }
</script>
<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
  <br>
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  <br>Using Regular expression
  <br>
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  <br>Using toLocaleString()
  <br>
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  <br>Using Intl.NumberFormat()
  <br>
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>

atuação

atuação http://jsben.ch/sifRd


Isso não funciona se você estiver digitando dinamicamente. Se você apenas der um valor a ele, ele funciona, mas se você estiver alimentando um valor constantemente dinamicamente, as vírgulas são adicionadas no lugar errado.
Edgar Quintero

Atualizei a demonstração abaixo da minha resposta. Ao inserir um valor dinâmico em uma caixa de texto. você testa tenta @EdgarQuintero
Tính Ngô Quang

39

Intl.NumberFormat

Função JS nativa. Suportado pelo IE11, Edge, Safari mais recente, Chrome, Firefox, Opera, Safari no iOS e Chrome no Android.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale

Minha resposta foi atualizada em resposta aos seus comentários. Obrigado!
Dustin Sun

35

Obrigado a todos por suas respostas. Eu desenvolvi algumas das respostas para criar uma solução mais "tamanho único".

O primeiro trecho acrescenta uma função que imita PHP é number_format()para o protótipo Number. Se estou formatando um número, normalmente quero casas decimais, para que a função receba o número de casas decimais a serem exibidas. Alguns países usam vírgulas como decimais e decimais como separador de milhares, para que a função permita que esses separadores sejam definidos.

Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.toFixed(decimals).split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);

    return parts.join(dec_point);
}

Você usaria isso da seguinte maneira:

var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00

Descobri que muitas vezes precisava recuperar o número para operações matemáticas, mas o parseFloat converte 5.000 em 5, simplesmente obtendo a primeira sequência de valores inteiros. Então, criei minha própria função de conversão de flutuador e a adicionei ao protótipo String.

String.prototype.getFloat = function(dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.split(dec_point);
    var re = new RegExp("[" + thousands_sep + "]");
    parts[0] = parts[0].replace(re, '');

    return parseFloat(parts.join(dec_point));
}

Agora você pode usar as duas funções da seguinte maneira:

var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;

console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00

2
Muito bom, peguei emprestado o primeiro método;) Mas ele não produz um resultado correto quando você deseja usar um formato europeu e o número é fracionário. A linha 5 deve ser:var parts = this.toFixed(decimals).toString().split('.');
vbwx 10/07/2013

Você está certo! toFixed () altera a vírgula para um ponto e, portanto, o '.' deve ser usado em vez de var dec_point. Obrigado por apontar isso.
Nenhum

você pode criar um módulo npm para isso?
Chovy

3
@ J.Money O .toString é desnecessário, o toFixed já retorna uma string.
Ariel #

Eu não sei por que você mencionou PHP aqui em tudo, ou dada uma função prototipical que já existe
vsync

27

Estou bastante impressionado com o número de respostas que esta pergunta tem. Eu gosto da resposta de uKolka :

n.toLocaleString()

Infelizmente, porém, em alguns locais como o espanhol, ele não funciona (IMHO) conforme o esperado para números abaixo de 10.000:

Number(1000).toLocaleString('ES-es')

1000e não 1.000.

Consulte toLocaleString que não funciona em números inferiores a 10000 em todos os navegadores para saber o motivo.

Então, eu tive que usar a resposta de Elias Zamaria escolhendo o caractere separador de milhares certo:

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Este funciona bem como uma linha para ambos os locais que usam ,ou .como separador de milhares e começa a trabalhar a partir de 1.000 em todos os casos.

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Fornece 1.000com um contexto de localidade em espanhol.

Se você deseja ter controle absoluto sobre a formatação de um número, tente também o seguinte:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)

1,234.57.

Este não precisa de uma expressão regular. Ele funciona ajustando o número para a quantidade desejada de decimais com toFixedprimeiro e, em seguida, dividindo-o em torno do ponto decimal, .se houver um. O lado esquerdo é então transformado em uma matriz de dígitos que é revertida. Em seguida, um separador de milhares é adicionado a cada três dígitos desde o início e o resultado é revertido novamente. O resultado final é a união das duas partes. O sinal do número de entrada é removido Math.absprimeiro e depois recolocado, se necessário.

Não é uma linha, mas não muito mais longa e facilmente transformada em função. As variáveis ​​foram adicionadas para maior clareza, mas essas podem ser substituídas pelos valores desejados, se forem conhecidos com antecedência. Você pode usar as expressões usadas toLocaleStringpara descobrir os caracteres corretos para o ponto decimal e o separador de milhares para o código do idioma atual (lembre-se de que esses requerem um Javascript mais moderno).


23

Eu acho que essa é a expressão regular mais curta que faz isso:

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")

Eu verifiquei em alguns números e funcionou.


só funciona bem se você não tiver um número flutuante com mais de 3 números após o separador, neste caso, um ponto. Caso contrário, ele adiciona uma vírgula também. "1234567890.1234567890". Substitua (/ \ B (? = (\ D {3}) + \ b) / g, ",") Isso não funcionaria, por exemplo. Retorna "1.234.567.890.1.234.567.890"
Marcio

1
Funciona bem para a moeda embora! Basta arredondar os dígitos antes de adicionar vírgulas.
Kyle Chadha

1
Adiciona, após o ponto decimal: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3.456
Shree Tiwari

21

Number.prototype.toLocaleString()teria sido incrível se fosse fornecido nativamente por todos os navegadores (Safari) .

Eu verifiquei todas as outras respostas, mas ninguém parecia preenchê-lo. Aqui está um ponto a favor disso, que na verdade é uma combinação das duas primeiras respostas; se toLocaleStringfunciona, usa-o; caso contrário, usa uma função personalizada.

var putThousandsSeparators;

putThousandsSeparators = function(value, sep) {
  if (sep == null) {
    sep = ',';
  }
  // check if it needs formatting
  if (value.toString() === value.toLocaleString()) {
    // split decimals
    var parts = value.toString().split('.')
    // format whole numbers
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
    // put them back together
    value = parts[1] ? parts.join('.') : parts[0];
  } else {
    value = value.toLocaleString();
  }
  return value;
};

alert(putThousandsSeparators(1234567.890));


1
Esteja ciente de que o polyfill funciona apenas com números com no máximo 3 casas decimais. Por exemplo: 0.12345será exibido 0.12,345. Uma boa aplicação para isso pode ser encontrada no underscore.string
Andy

você está certo, colocar uma value > 1000condição if corrige esse caso, no entanto, esse foi um problema e, é claro, versões mais testadas podem ser encontradas em outros lugares, obrigado por apontar.
Sinan

1
Não basta colocar value > 1000, porque seria o mesmo para qualquer número e com mais de três casas decimais. por exemplo, 1000.12345retornos 1,000.12,345. Sua resposta é ótima e no caminho certo, mas não está completa. Eu só estava tentando apontar para outras pessoas que podem tropeçar na sua resposta e apenas copiar / colar sem testar com dados de entrada diferentes.
Andy

1
tudo bem, isso precisava de outra edição :) Eu concordo, mas agora pelo menos deve funcionar na maioria dos casos.
Sinan

18

O separador de milhares pode ser inserido de maneira internacional, usando o Intlobjeto do navegador :

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

Consulte o artigo da MDN sobre NumberFormat para obter mais informações, você pode especificar o comportamento da localidade ou o padrão para o usuário. Isso é um pouco mais infalível, porque respeita as diferenças locais; muitos países usam períodos para separar dígitos, enquanto uma vírgula indica os decimais.

O Intl.NumberFormat ainda não está disponível em todos os navegadores, mas funciona nos mais recentes Chrome, Opera e IE. O próximo lançamento do Firefox deve suportá-lo. O Webkit não parece ter um cronograma para implementação.


2
Embora isso fosse incrível se pudéssemos usar uma função interna simples, ela tem uma implementação terrível do navegador. Por exemplo, IE 8-10 e todos esquentar Safari apoiar esta
Blaine Kasten

@BlaineKasten, há um polyfill totalmente compatível para navegadores mais antigos disponível aqui: github.com/andyearnshaw/Intl.js é enorme, mas funciona.
Mahn

1
Disponível através de um pollyfill CDN (retorna somente o que é necessário com base em useragent): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Kevin

Questões tiveram formatação grandes números com toLocaleString, isso funcionou muito bem (com polyfill)
asked_io


14

se você estiver lidando com valores de moeda e formatando muito, talvez valha a pena adicionar o accounting.js minúsculo, que lida com muitos casos extremos e localização:

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values are formatted nicely, too:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

1
O link não funciona mais. Mas parece semelhante a este: openexchangerates.github.io/accounting.js
ush189

13

O código a seguir usa char scan, portanto, não há regex.

function commafy( num){
  var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
  while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                  +s.charAt(i) +o }
  return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
}

Ele mostra um desempenho promissor: http://jsperf.com/number-formatting-with-commas/5

26/04/2015: Correção menor para resolver o problema quando num <0. Consulte https://jsfiddle.net/runsun/p5tqqvs3/


isso não funciona com o commafy(-123456)que dá #-,123,456
wrossmck 13/03/14

Isso é ótimo! Obrigado por unir o JSPerf
fregante

Este trecho é um monstro absoluto, fora executa tudo.
NiCk Newman

13

Aqui está uma função simples que insere vírgulas para milhares de separadores. Ele usa funções de matriz em vez de um RegEx.

/**
 * Format a number as a string with commas separating the thousands.
 * @param num - The number to be formatted (e.g. 10000)
 * @return A string representing the formatted number (e.g. "10,000")
 */
var formatNumber = function(num) {
    var array = num.toString().split('');
    var index = -3;
    while (array.length + index > 0) {
        array.splice(index, 0, ',');
        // Decrement by 4 since we just added another unit to the array.
        index -= 4;
    }
    return array.join('');
};

Link do CodeSandbox com exemplos: https://codesandbox.io/s/p38k63w0vq


1
Olá .. Este exemplo é ótimo. Mas colocará vírgulas para a parte decimal também. apenas uma edição: function formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (divisão de número ('.') [0]); } var array = num.toString (). split (''); índice var = -3; while (array.length + index> 0) {array.splice (índice, 0, ','); // Decrementa em 4, pois acabamos de adicionar outra unidade à matriz. índice - = 4; } retornar array.join ('') + decimalPart; };
Aki143S

Obrigado senhor. Isso é exatamente o que eu precisava.
Amir Hossein Ahmadi

11

Use este código para lidar com o formato de moeda da Índia. O código do país pode ser alterado para lidar com a moeda de outro país.

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

resultado:

3,50,256.95

Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta. Leia isto .
Shanteshwar Inde 12/03/19

@ShanteshwarInde i irá adicionar contexto adicional para melhorar a resposta certeza
Bathri Nathan

11

Você também pode usar o construtor Intl.NumberFormat . Aqui está como você pode fazer isso.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 

este nó não está funcionando js. Não está dando resposta em formato indiano
Suraj Dalvi

7

Eu escrevi este antes de tropeçar neste post. Sem regex e você pode realmente entender o código.

$(function(){
  
  function insertCommas(s) {

    // get stuff before the dot
    var d = s.indexOf('.');
    var s2 = d === -1 ? s : s.slice(0, d);

    // insert commas every 3 digits from the right
    for (var i = s2.length - 3; i > 0; i -= 3)
      s2 = s2.slice(0, i) + ',' + s2.slice(i);

    // append fractional part
    if (d !== -1)
      s2 += s.slice(d);

    return s2;

  }
  
  
  $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>


1
Adicionei s.toString () no início da função para que ele também aceite números, não apenas strings. Esta é a minha resposta preferida porque é legível, concisa e não possui nenhum dos erros que as respostas regex parecem ter.
FeFiFoFu 12/01

7
var formatNumber = function (number) {
  var splitNum;
  number = Math.abs(number);
  number = number.toFixed(2);
  splitNum = number.split('.');
  splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return splitNum.join(".");
}

EDIT: A função funciona apenas com número positivo. por exemplo:

var number = -123123231232;
formatNumber(number)

Saída: "123,123,231,232"

Mas, para responder à pergunta acima, o toLocaleString()método apenas resolve o problema.

var number = 123123231232;
    number.toLocaleString()

Saída: "123,123,231,232"

Elogio!


1
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta.
Donald Duck

1
Bom script, mas não funciona com números negativos.
Ralph David Abernathy

7

Minha resposta é a única resposta que substitui completamente o jQuery por uma alternativa muito mais sensata:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}

Essa solução não apenas adiciona vírgulas, mas também arredonda para o centavo mais próximo, caso você insira uma quantia como a de $(1000.9999)US $ 1.001,00. Além disso, o valor inserido pode ser um número ou uma string com segurança; Não importa.

Se você está lidando com dinheiro, mas não quer um cifrão à esquerda, também pode adicionar esta função, que usa a função anterior, mas remove $:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

Se você não está lidando com dinheiro e tem vários requisitos de formatação decimal, aqui está uma função mais versátil:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}

Ah, e a propósito, o fato de esse código não funcionar em alguma versão antiga do Internet Explorer é completamente intencional. Eu tento interromper o IE a qualquer momento que eu possa pegá-lo sem suportar os padrões modernos.

Lembre-se de que elogios excessivos, na seção de comentários, são considerados fora de tópico. Em vez disso, apenas me regue com votos positivos.


1
O Number (n) .toLocaleString () parece a melhor resposta, mas você provavelmente desejaria usar algo como o novo formato Intl.NumberFormat ('en-US'). (N) em vez de retirar os cifrões e decimais, se todos os o usuário deseja possui vírgulas em seu número.
precisa saber é o seguinte

@bmacnaughton: Esse é um bom ponto quando você não está lidando com dinheiro. No entanto, se você está lidando com dinheiro e apenas "não deseja o sinal de dólar inicial", Number (1000.50) .toLocaleString () produz '1.000.5', que remove o zero insignificante que normalmente é mantido ao exibir valores monetários. Bom comentário: todos devem saber o que você disse.
Lonnie Best

6

Para mim, a melhor resposta é usar toLocaleString como alguns membros disseram. Se você deseja incluir o símbolo '$', basta adicionar o idioma e digitar as opções. Aqui está e exemplo para formatar um número para pesos mexicanos

var n = 1234567.22
alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))

atalho

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})

5

Deixe-me tentar melhorar a resposta do uKolka e talvez ajudar outras pessoas a economizar algum tempo.

Use Numeral.js .

document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>

Você deve usar Number.prototype.toLocaleString () apenas se a compatibilidade do navegador não for um problema.


isso me inspirou a npm instalar numeral
steampowered

5

Uma maneira alternativa, suportando decimais, diferentes separadores e negativos.

var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
    var ts      = ( thousand_sep == null ? ',' : thousand_sep )
        , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
        , dp    = ( decimal_pos  == null ? 2   : decimal_pos )

        , n     = Math.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + parseFloat(number).toFixed(dp).split('.')[1]

    return f;
}

Algumas correções feitas por @Jignesh Sanghani, não se esqueça de votar neste comentário.


Perfeito para mim, acabei de adicionar uma nova linha para remover a formatação antes do processamento.
Dennis Heiden

2
fn.substr(0, i)substitua por n.substr(0, i)e também number.toFixed(dp).split('.')[1]substitua por parseFloat(number).toFixed(dp).split('.')[1]. porque quando eu uso diretamente é me dar um erro. atualize seu código
Jignesh Sanghani

falho. número cresce. uma chamada de exame teria sido ótima!
mmm

mudar o teto para o chão fixou isso, mas sem saber quais outros problemas surgirão.
mmm

1
Tente Math.floor (-75.1);)
mmm

4

Eu acho que essa função cuidará de todos os problemas relacionados a esse problema.

function commaFormat(inputString) {
    inputString = inputString.toString();
    var decimalPart = "";
    if (inputString.indexOf('.') != -1) {
        //alert("decimal number");
        inputString = inputString.split(".");
        decimalPart = "." + inputString[1];
        inputString = inputString[0];
        //alert(inputString);
        //alert(decimalPart);

    }
    var outputString = "";
    var count = 0;
    for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
        //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
        if (count == 3) {
            outputString += ",";
            count = 0;
        }
        outputString += inputString.charAt(i);
        count++;
    }
    if (inputString.charAt(0) == '-') {
        outputString += "-";
    }
    //alert(outputString);
    //alert(outputString.split("").reverse().join(""));
    return outputString.split("").reverse().join("") + decimalPart;
}

4

Apenas para futuros googlers (ou não necessariamente 'googlers'):

Todas as soluções mencionadas acima são maravilhosas, no entanto, o RegExp pode ser uma coisa muito ruim de se usar em uma situação como essa.

Então, sim, você pode usar algumas das opções propostas ou até escrever algo primitivo, mas útil como:

const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

O regexp usado aqui é bastante simples e o loop será precisamente o número de vezes necessário para concluir o trabalho.

E você pode otimizar muito melhor o código "DRYify" e assim por diante.

Ainda,

(-1234567.0987).toLocaleString();

(na maioria das situações) seria uma escolha muito melhor.

O ponto não está na velocidade de execução ou na compatibilidade entre navegadores.

Nas situações em que você deseja mostrar o número resultante ao usuário, o método .toLocaleString () fornece a você o poder de falar o mesmo idioma com o usuário do seu site ou aplicativo (qualquer que seja o idioma dele).

Esse método, de acordo com a documentação do ECMAScript, foi introduzido em 1999, e acredito que a razão disso tenha sido a esperança de que a Internet, em algum momento, conectasse pessoas em todo o mundo, portanto, eram necessárias algumas ferramentas de "internalização".

Hoje a Internet conecta todos nós, portanto, é importante lembrar que o mundo é muito mais complexo do que imaginamos e que (/ quase) todos nós estamos aqui , na Internet.

Obviamente, considerando a diversidade de pessoas, é impossível garantir a experiência do usuário perfeita para todos, porque falamos idiomas diferentes, valorizamos coisas diferentes, etc. E exatamente por isso, é ainda mais importante tentar localizar as coisas o máximo possível .

Portanto, considerando que existem alguns padrões específicos para representação de data, hora, números etc. e que temos uma ferramenta para exibir essas coisas no formato preferido pelo usuário final, não é raro e quase irresponsável não usar essa ferramenta (especialmente em situações em que queremos exibir esses dados para o usuário)?

Para mim, usar RegExp em vez de .toLocaleString () em situações como essa parece um pouco como criar um aplicativo de relógio com JavaScript e codificá-lo de maneira a exibir apenas o tempo de Praga (o que seria bastante inútil para pessoas que não vivem em Praga), embora o comportamento padrão de

new Date();

é retornar os dados de acordo com o relógio do usuário final.


por que você escreveu a função com const e =>?
OG Sean

@OGSean eu sempre faço, pois é a maneira mais conveniente de declarar variáveis ​​e funções. Além disso, acho que ajuda a manter o código mais limpo e mais curto.
Igor Bykov

4

Minha " verdadeira " solução apenas de expressões regulares para aqueles que adoram uma só palavra

Você vê esses jogadores entusiasmados acima? Talvez você possa jogar fora disso. Aqui está o meu derrame.

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

Usa um ESPAÇO FINO (U + 2009) para um separador de milhares, como o Sistema Internacional de Unidades disse na oitava edição (2006) de sua publicação “ Brochura da SI: Sistema Internacional de Unidades (SI) (Veja §5.3 .4.). A nona edição (2019) sugere usar um espaço para isso (ver §5.4.4.). Você pode usar o que quiser, incluindo uma vírgula.


Vejo.

const integer_part_only = n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ");
const fractional_part_only = n => `${n}`.replace(/(?<=\.(\d{3})+)\B/g, " F ");
const both = n => fractional_part_only(integer_part_only(n));

function demo(number) { // I’m using Chrome 74.
	console.log(`${number}
		 "${integer_part_only(number)}" (integer part only)
		 "${fractional_part_only(number)}" (fractional part only)
		 "${both(number)}" (both)
	`);
}
demo(Math.random() * 10e5);
demo(123456789.01234567);
demo(123456789);
demo(0.0123456789);


Como funciona?

Para uma parte inteira

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") Coloque "eu"
    • /……/g em cada um
      • \B entre dois dígitos adjacentes
        • (?=……)VISÃO POSITIVA cuja parte direita é
          • (\d{3})+ um ou mais pedaços de três dígitos
          • \b seguido por um não dígito, como um ponto final, o fim da string, etc.
        • (?<!……)OLHAR NEGATIVO, excluindo aqueles cuja parte esquerda
          • \.\d+ é um ponto seguido de dígitos ("possui um separador decimal").

Para uma parte decimal

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") Coloque "F"
    • /……/g em cada um
      • \B entre dois dígitos adjacentes
        • (?<=……)VISUALIZAÇÃO POSITIVA, cuja parte esquerda é
          • \. um separador decimal
          • (\d{3})+ seguido por um ou mais blocos de três dígitos.

Classes e limites de caracteres

\d

Corresponde a qualquer dígito (algarismo arábico). Equivalente a [0-9].

Por exemplo,

  • /\d/ou /[0-9]/corresponde 2em B2 is the suite number.

\b

Corresponde a um limite de palavras . Essa é a posição em que um caractere de palavra não é seguido ou precedido por outro caractere de palavra, como entre uma letra e um espaço. Observe que um limite de palavras correspondentes não está incluído na correspondência. Em outras palavras, o comprimento de um limite de palavra correspondente é zero.

Exemplos:

  • /\bm/corresponde ao min moon;
  • /oo\b/não corresponde ao ooin moon, porque ooé seguido por nqual é um caractere de palavra;
  • /oon\b/corresponde ao oonin moon, porque ooné o fim da string, não sendo seguido por um caractere de palavra;
  • /\w\b\w/ nunca corresponderá a nada, porque um caractere de palavra nunca pode ser seguido por um caractere que não seja uma palavra e um caractere de palavra.

\B

Corresponde a um limite de não palavra . Essa é uma posição em que o caractere anterior e o próximo são do mesmo tipo: ambos devem ser palavras ou ambos não devem ser palavras. Como entre duas letras ou entre dois espaços. O início e o fim de uma string são considerados não-palavras. Igual ao limite de palavras correspondidas, o limite de não palavras correspondidas também não é incluído na correspondência.

Por exemplo,

  • /\Bon/corresponde onem at noon;
  • /ye\B/corresponde yeem possibly yesterday.

Compatibilidade do navegador


3

Adicionei tofixed à solução do Aki143S . Esta solução usa pontos para separadores de milhares e vírgula para precisão.

function formatNumber( num, fixed ) { 
    var decimalPart;

    var array = Math.floor(num).toString().split('');
    var index = -3; 
    while ( array.length + index > 0 ) { 
        array.splice( index, 0, '.' );              
        index -= 4;
    }

    if(fixed > 0){
        decimalPart = num.toFixed(fixed).split(".")[1];
        return array.join('') + "," + decimalPart; 
    }
    return array.join(''); 
};

Exemplos;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454

3

Muitas boas respostas já. Aqui está outro, apenas por diversão:

function format(num, fix) {
    var p = num.toFixed(fix).split(".");
    return p[0].split("").reduceRight(function(acc, num, i, orig) {
        if ("-" === num && 0 === i) {
            return num + acc;
        }
        var pos = orig.length - i - 1
        return  num + (pos && !(pos % 3) ? "," : "") + acc;
    }, "") + (p[1] ? "." + p[1] : "");
}

Alguns exemplos:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"

isso não funciona com o format(-123456)que dá #-,123,456
wrossmck 13/03/14

1
Corrigido (embora exista provavelmente uma maneira mais elegante de fazer isso sem verificar o sinal todas as vezes). De qualquer forma, a atualização faz esse trabalho com números negativos.
Wayne
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.