Cara mencetak nomor dengan koma sebagai ribuan pemisah dalam JavaScript

1784

Saya mencoba untuk mencetak bilangan bulat dalam JavaScript dengan koma sebagai pemisah ribuan. Misalnya, saya ingin menunjukkan nomor 1234567 sebagai "1.234.567". Bagaimana saya bisa melakukan ini?

Inilah cara saya melakukannya:

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

Apakah ada cara yang lebih sederhana atau lebih elegan untuk melakukannya? Akan lebih baik jika bekerja dengan pelampung juga, tetapi itu tidak perlu. Tidak perlu spesifik lokal untuk memutuskan antara periode dan koma.

Elias Zamaria
sumber
156
Nomor (x) .toLocaleString ()
Boffin
@Boffin ini tidak berfungsi untuk nomor jenis input (karena koma) - dalam jawaban yang diterima kita dapat mengganti koma ke titik dan nomor jenis input akan berfungsi
Vitaly Zdanevich
48
Perlu dicatat bahwa Number.prototype.toLocaleString masih tidak berfungsi di Safari, pada tahun 2016 . Alih-alih benar-benar memformat angka, itu hanya mengembalikannya, tidak ada kesalahan yang dilemparkan. Mempunyai facepalm terbesar hari ini sebagai hasil dari ... #goodworkApple
aendrew
Namun, tampaknya berfungsi di safari iOS.
Tim
toLocaleString tidak konsisten dan tidak boleh digunakan. Misalnya - di Firefox ini akan mengembalikan 1.234 tetapi di IE ini akan menambahkan desimal: 1.234.00
Bort

Jawaban:

2837

Saya menggunakan ide dari jawaban Kerry, tetapi menyederhanakannya karena saya hanya mencari sesuatu yang sederhana untuk tujuan spesifik saya. Inilah yang saya lakukan:

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


Regex menggunakan 2 pernyataan lookahead:

  • yang positif untuk mencari titik mana pun dalam string yang memiliki kelipatan 3 digit berturut-turut setelahnya,
  • pernyataan negatif untuk memastikan bahwa titik tersebut hanya memiliki kelipatan 3 digit. Ekspresi pengganti menempatkan koma di sana.

Misalnya, jika Anda melewatinya 123456789.01, pernyataan positif akan cocok dengan setiap tempat di sebelah kiri 7 (karena 789kelipatan 3 digit, 678kelipatan 3 digit 567, dll.). Pernyataan negatif memeriksa bahwa kelipatan 3 digit tidak memiliki digit apa pun setelahnya. 789memiliki titik setelahnya sehingga persis kelipatan 3 digit, jadi koma ada di sana. 678adalah kelipatan dari 3 digit tetapi memiliki 9setelah itu, sehingga 3 digit tersebut adalah bagian dari grup 4, dan koma tidak pergi ke sana. Demikian pula untuk 567. 456789adalah 6 digit, yang merupakan kelipatan dari 3, jadi koma berjalan sebelum itu. 345678adalah kelipatan dari 3, tetapi memiliki 9setelahnya, jadi tidak ada koma di sana. Dan seterusnya. Itu\B menjaga regex dari meletakkan koma di awal string.

@ neu-rah menyebutkan bahwa fungsi ini menambahkan koma di tempat yang tidak diinginkan jika ada lebih dari 3 digit setelah titik desimal. Jika ini merupakan masalah, Anda dapat menggunakan fungsi ini:

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

@ tjcrowder menunjukkan bahwa sekarang JavaScript telah melihat di belakang ( info dukungan ), itu dapat diselesaikan dalam ekspresi reguler itu sendiri:

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

(?<!\.\d*)adalah pandangan negatif di belakang yang mengatakan bahwa pertandingan tidak dapat didahului oleh angka .nol atau lebih yang diikuti. Tampilan negatif di belakang lebih cepat daripada splitdan joinsolusi ( perbandingan ), setidaknya dalam V8.

Elias Zamaria
sumber
21
Sangat keren, apakah memperhatikan bahwa ia memiliki masalah dengan angka yang memiliki lebih dari 3 tempat setelah titik desimal.
Eric Petroelje
60
coba numberWithCommas (12345.6789) -> "12.345.6.789" saya tidak menyukainya
neu-rah
4
Itu tidak bekerja dengan baik dengan pecahan, kami tidak ingin memiliki koma setelah titik desimal
Mugen
30
Perbaikan kecil yang diperbaiki setelah '.' masalah '123456789.01234'.replace (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g,' _ ')
Dmitrij Golubev
8
@DmitrijGolubev Tidak berfungsi untuk bilangan bulat. Mungkin memaksakan titik desimal akan menjadi solusinya.
Vlad
1809

Saya terkejut tidak ada yang menyebutkan Number.prototype.toLocaleString . Ini diimplementasikan dalam JavaScript 1.5 (yang diperkenalkan pada tahun 1999) sehingga pada dasarnya didukung di semua browser utama.

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

Ia juga bekerja di Node.js pada v0.12 melalui penyertaan Intl

Perhatikan saja bahwa fungsi ini mengembalikan string, bukan angka.

Jika Anda menginginkan sesuatu yang berbeda, Numeral.js mungkin menarik.

uKolka
sumber
17
@ skigrist Poin bagus, tapi sepertinya tidak seburuk yang terlihat. Kecepatan tergantung pada browser. Dalam FF atau Opera berkinerja baik. Saya mengisap Chrome. Adapun nol: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"Opsi-opsi itu tidak bekerja di FF atau Safari sekalipun.
uKolka
22
Perbedaan kinerja mungkin atau mungkin bukan masalah, tergantung pada konteksnya. Jika digunakan untuk tabel raksasa 1000 hasil maka itu akan lebih penting tetapi jika hanya digunakan untuk nilai tunggal, perbedaannya dapat diabaikan. Tetapi keuntungannya adalah itu adalah lokal-sadar, jadi seseorang di Eropa akan melihat 34.523.453.345 atau 34 523 453.345 . Ini akan lebih penting di situs dengan pengunjung dari banyak negara.
T Nguyen
6
Luar biasa. Akhirnya jawaban dengan fungsi asli. Dan terlebih lagi, yang ini ditampilkan dengan benar di berbagai negara dengan pemisah yang berbeda (di Republik Ceko kami tulis X XXX XXX,YYY).
Tomáš Zato - Reinstate Monica
22
Pembaruan untuk googler: toLocaleStringbekerja di Node.js pada v0.12 melalui penyertaan Intl .
srobinson
8
@MSC Anda harus mencoba parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})atau new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})sebagai gantinya. Ini tidak berfungsi karena Anda menggunakannya pada string, bukan angka.
uKolka
244
var number = 1234567890; // Example number to be converted

⚠ Pikirkan bahwa javascript memiliki nilai integer maksimum 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 tidak didukung):

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

Dari apa yang saya periksa (setidaknya Firefox) keduanya kurang lebih sama tentang kinerja.

vsync
sumber
6
NumberFormat tidak didukung di Safari, untuk siapa pun yang menerapkan di sana.
marcovega
6
toLocaleString juga tidak didukung di safari
Deepak Banka
3
Dukungan browser selalu disebutkan di bagian bawah setiap halaman MDN, yang telah saya tautkan.
vsync
5
toLocaleStringkarya dasar tentang safari, opsi tidak
dandavis
3
yang toLocaleStringsolusi harus mungkin juga termasuk lokal yang diinginkan, sehingga toLocaleString("en"), karena Inggris menggunakan pola koma. Namun, jika toLocaleString()tanpa indikator lokal dijalankan di Perancis, maka itu akan menghasilkan periode alih-alih koma karena itulah yang digunakan untuk memisahkan ribuan secara lokal.
Mike 'Pomax' Kamermans
112

Saya sarankan menggunakan number_format () 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);
}

UPDATE 02/13/14

Orang-orang telah melaporkan ini tidak berfungsi seperti yang diharapkan, jadi saya melakukan JS Fiddle yang mencakup tes otomatis.

Pembaruan 26/11/2017

Berikut biola itu sebagai Cuplikan Stack dengan output yang sedikit dimodifikasi:

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

Kerry Jones
sumber
Bukan berarti saya menandainya, tetapi saya percaya orang melakukannya karena tidak berhasil. Seperti berdiri saya menemukan beberapa tes Anda untuk tidak bekerja.
Andrew S
3
@Andrew S - Hanya 1 orang yang menandainya. Itu berhasil, saya telah menggunakannya dalam kode saya sendiri berkali-kali. Ini juga bukan kode saya (atau tes saya), saya mereferensikan situs asalnya, yang merupakan situs terkenal. Mungkin mereka memiliki versi terbaru dari itu) karena kode yang Anda lihat adalah 3 tahun.
Kerry Jones
13
@ernix - Operator meminta JavaScript, jawaban yang saya berikan adalah JavaScript. Ini adalah interpretasi JavaScript untuk fungsi PHP.
Kerry Jones
2
@ernix - berfungsi persis seperti yang diharapkan dengan contoh yang diberikan OP. Saya menaruh biola sehingga Anda bisa melihat.
Kerry Jones
4
@ernix - Oke, tetapi intinya adalah bahwa ia melakukan persis apa yang diminta OP. Itu dari situs lain (tidak dikelola oleh saya, dan saya sudah menyatakan ini sebelumnya), dan ketika memberikan variabel yang tepat, ia berfungsi persis seperti yang dinyatakan. Jika Anda yakin itu adalah bug, hubungi phpjs.org atau lihat apakah mereka memiliki versi yang diperbarui.
Kerry Jones
75

Ini adalah variasi dari jawaban @ mikez302, tetapi dimodifikasi untuk mendukung angka dengan desimal (per umpan balik @ neu-rah bahwa numberWithCommas (12345.6789) -> "12.345.6.789" bukan "12.345.6789"

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
pengguna1437663
sumber
1
Hai, lihat, Anda adalah kontributor open-source :)
Jacob Stamm
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
Tutankhamen
sumber
Apa yang dilakukan jawaban saya ini? Regex terlihat sedikit berbeda tetapi sepertinya harus melakukan hal yang sama.
Elias Zamaria
8
lebih pendek :)
Tutankhamen
4
Ini elegan. Persis apa yang saya cari.
tradisional
4
Dari blog.tompawlak.org/number-currency-formatting-javascript ? Masalah yang diketahui: formatNumber (0.123456) = 0.123.456 Tidak adanya tampilan di JS membuatnya sulit untuk memperbaikinya dengan regex yang elegan.
Vlad
1
123456789.123456789.toString (). Ganti (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1,') => 123.456.789.12345679
kenberkeley
53

Menggunakan ekspresi Reguler

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

Menggunakan 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 ()

Menggunakan 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 DI SINI

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

Performa

Performa http://jsben.ch/sifRd

Tính Ngô Quang
sumber
Ini tidak berfungsi jika Anda mengetik secara dinamis. Jika Anda hanya memberikan nilai, itu berfungsi, tetapi jika Anda memberi nilai secara konstan secara dinamis, koma ditambahkan di tempat yang salah.
Edgar Quintero
Saya telah memperbarui demo di bawah jawaban saya. Saat memasukkan nilai dinamis dalam kotak teks. Anda menguji coba @ EdgarQuintero
Tính Ngô Quang
39

Intl.NumberFormat

Fungsi JS asli. Didukung oleh IE11, Edge, Safari terbaru, Chrome, Firefox, Opera, Safari di iOS dan Chrome di Android.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
Dustin Sun
sumber
Jawaban saya diperbarui sebagai tanggapan terhadap komentar Anda. Terima kasih!
Dustin Sun
35

Terima kasih untuk semua orang atas balasan mereka. Saya telah membangun beberapa jawaban untuk membuat solusi yang lebih "satu ukuran untuk semua".

Potongan pertama menambahkan fungsi yang meniru PHP 's number_format()untuk prototipe Nomor. Jika saya memformat angka, saya biasanya ingin tempat desimal sehingga fungsinya menunjukkan jumlah tempat desimal untuk ditampilkan. Beberapa negara menggunakan koma sebagai desimal dan desimal sebagai pemisah ribuan sehingga fungsinya memungkinkan pemisah ini diatur.

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

Anda akan menggunakan ini sebagai berikut:

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

Saya menemukan bahwa saya sering perlu mendapatkan nomor kembali untuk operasi matematika, tetapi parseFloat mengubah 5.000 menjadi 5, hanya mengambil urutan pertama dari nilai integer. Jadi saya membuat fungsi konversi float saya sendiri dan menambahkannya ke prototipe 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));
}

Sekarang Anda dapat menggunakan kedua fungsi sebagai berikut:

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
Tidak ada
sumber
2
Sangat bagus, saya meminjam metode pertama;) Tetapi tidak menghasilkan hasil yang benar ketika Anda ingin menggunakan format Eropa dan jumlahnya fraksional. Baris 5 seharusnya:var parts = this.toFixed(decimals).toString().split('.');
vbwx
Kamu benar! toFixed () mengubah koma ke periode dan jadi '.' harus digunakan sebagai ganti var dec_point. Terima kasih telah menunjukkannya.
Tidak ada
dapatkah Anda membuat modul npm untuk ini?
chovy
3
@ J.Money .toString tidak perlu, toFixed sudah mengembalikan string.
Ariel
Saya tidak tahu mengapa Anda menyebutkan PHP di sini, atau memberikan fungsi prototipikal yang sudah ada
vsync
27

Saya cukup terkesan dengan jumlah jawaban yang didapat pertanyaan ini. Saya suka jawabannya oleh uKolka :

n.toLocaleString()

Namun sayangnya, di beberapa lokal seperti Spanyol, itu tidak berfungsi (IMHO) seperti yang diharapkan untuk angka di bawah 10.000:

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

Memberi 1000dan tidak 1.000.

Lihat toLocaleString yang tidak bekerja pada angka kurang dari 10.000 di semua browser untuk mengetahui alasannya.

Jadi saya harus menggunakan jawaban oleh Elias Zamaria memilih karakter pemisah ribuan yang tepat:

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

Yang ini berfungsi baik sebagai satu-liner untuk kedua lokal yang menggunakan ,atau .sebagai pemisah ribuan dan mulai bekerja dari 1.000 dalam semua kasus.

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

Memberi 1.000dengan konteks lokal Spanyol.

Jika Anda ingin memiliki kontrol mutlak atas cara angka diformat, Anda juga dapat mencoba yang berikut:

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)

Memberi 1,234.57.

Yang ini tidak perlu ekspresi reguler. Ia bekerja dengan menyesuaikan angka dengan jumlah desimal yang diinginkan dengan yang toFixedpertama, kemudian membaginya di sekitar titik desimal .jika ada. Sisi kiri kemudian diubah menjadi array angka yang dibalik. Kemudian pemisah ribuan ditambahkan setiap tiga digit dari awal dan hasilnya dibalik lagi. Hasil akhirnya adalah penyatuan dua bagian. Tanda nomor input dihapus dengan Math.absterlebih dahulu dan kemudian dimasukkan kembali jika perlu.

Ini bukan satu-liner tetapi tidak lebih lama dan mudah berubah menjadi fungsi. Variabel telah ditambahkan untuk kejelasan, tetapi mereka dapat diganti dengan nilai yang diinginkan jika diketahui sebelumnya. Anda dapat menggunakan ekspresi yang digunakan toLocaleStringsebagai cara untuk mengetahui karakter yang tepat untuk titik desimal dan pemisah ribuan untuk lokal saat ini (perlu diingat bahwa mereka memerlukan Javascript yang lebih modern.)

Elices Javier
sumber
23

Saya pikir ini adalah ekspresi reguler terpendek yang melakukannya:

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

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

Saya memeriksanya di beberapa nomor dan berhasil.

pengguna3664916
sumber
berfungsi dengan baik jika Anda tidak memiliki angka float dengan lebih dari 3 angka setelah pemisah dalam kasus ini sebuah titik. Kalau tidak, ia menambahkan koma juga. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Ini tidak akan berfungsi misalnya. Pengembalian "1.234.567.890.1.234.567.890"
Marcio
1
Bekerja dengan baik untuk mata uang! Bulatkan digit Anda sebelum menambahkan koma.
Kyle Chadha
1
Ini Menambah, Setelah titik Desimal: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3.456
Shree Tiwari
21

Number.prototype.toLocaleString()akan luar biasa jika disediakan secara native oleh semua browser (Safari) .

Saya memeriksa semua jawaban lain tetapi tampaknya tidak ada yang mengisinya. Berikut ini adalah titik menuju itu, yang sebenarnya merupakan kombinasi dari dua jawaban pertama; jika toLocaleStringberfungsi, gunakan, jika tidak, gunakan fungsi khusus.

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

Sinan
sumber
1
Ketahuilah bahwa polyfill hanya berfungsi dengan angka yang memiliki paling banyak 3 desimal. Sebagai contoh: 0.12345akan menampilkan 0.12,345. Implementasi yang baik untuk ini dapat ditemukan di underscore.string
Andy
Anda benar, meletakkan value > 1000ke jika kondisi memperbaiki kasus itu, namun ini adalah poc dan tentu saja versi yang lebih baik dapat ditemukan di tempat lain, terima kasih telah menunjukkan.
Sinan
1
Itu tidak cukup untuk dimasukkan value > 1000, karena itu akan sama untuk angka berapa pun dan lebih dari 3 desimal. misalnya 1000.12345pengembalian 1,000.12,345. Jawaban Anda bagus dan berada di jalan yang benar, tetapi tidak lengkap. Saya hanya mencoba menunjukkan kepada orang lain yang mungkin tersandung pada jawaban Anda dan hanya menyalin / menempelnya tanpa pengujian dengan data input yang berbeda.
Andy
1
baik-baik saja, ini membutuhkan suntingan lain :) Saya setuju, tapi sekarang setidaknya itu berfungsi untuk sebagian besar kasus.
Sinan
18

Pemisah ribuan dapat dimasukkan dengan cara yang ramah internasional menggunakan objek browser Intl:

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

Lihat artikel MDN di NumberFormat untuk lebih lanjut, Anda dapat menentukan perilaku lokal atau default untuk pengguna. Ini sedikit lebih mudah karena menghargai perbedaan lokal; banyak negara menggunakan periode untuk memisahkan digit sementara koma menunjukkan desimal.

Intl.NumberFormat belum tersedia di semua browser, tetapi berfungsi di Chrome, Opera, & IE terbaru. Rilis Firefox berikutnya harus mendukungnya. Webkit tampaknya tidak memiliki garis waktu untuk implementasi.

phette23
sumber
2
Meskipun ini akan luar biasa jika kita dapat menggunakan fungsi bawaan yang sederhana, ini memiliki implementasi browser yang buruk. Sebagai contoh, IE 8-10 dan semua Safari tidak mendukung ini
Blaine Kasten
@ BlaineKasten ada polyfill yang sepenuhnya kompatibel untuk browser lama yang tersedia di sini: github.com/andyearnshaw/Intl.js ini sangat besar, tetapi berfungsi.
Mahn
1
Tersedia melalui CDN pollyfill (hanya mengembalikan apa yang diperlukan berdasarkan agen pengguna): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Kevin
Seandainya masalah memformat angka besar dengan toLocaleString, ini bekerja sangat baik (dengan polyfill)
ask_io
18

Anda dapat menggunakan prosedur ini untuk memformat mata uang Anda.

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

Untuk info lebih lanjut, Anda dapat mengakses tautan ini.

https://www.justinmccandless.com/post/formatting-currency-in-javascript/

Dulith De Costa
sumber
Ini adalah jawaban yang benar, portabel, asli. Seandainya saya bisa memilih lebih dari satu kali.
Jared Smith
14

jika Anda berurusan dengan nilai mata uang dan banyak memformat, mungkin ada baiknya menambahkan accounting.js kecil yang menangani banyak kasus tepi dan pelokalan:

// 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
Shital Shah
sumber
1
Tautan tidak berfungsi lagi. Tetapi terlihat mirip dengan yang ini: openexchangerates.github.io/accounting.js
ush189
13

Kode berikut menggunakan char scan, jadi tidak ada 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] : ''); 
}

Ini menunjukkan kinerja yang menjanjikan: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Perbaikan kecil untuk menyelesaikan masalah ketika jumlah <0. Lihat https://jsfiddle.net/runsun/p5tqqvs3/

Runeun
sumber
ini tidak bekerja dengan commafy(-123456)itu memberi-,123,456
wrossmck
Ini bagus! Terima kasih telah mengumpulkan jsperf
fregante
Cuplikan ini adalah monster absolut, yang melakukan semuanya.
NiCk Newman
13

Berikut adalah fungsi sederhana yang memasukkan koma untuk ribuan pemisah. Ini menggunakan fungsi array daripada 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('');
};

Tautan CodeSandbox dengan contoh: https://codesandbox.io/s/p38k63w0vq

Noah Freitas
sumber
1
Hai .. Contoh ini bagus. Tetapi itu juga akan menempatkan koma untuk bagian desimal. hanya edit: function formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (num.split ('.') [0]); } var array = num.toString (). split (''); indeks var = -3; while (array.length + index> 0) {array.splice (index, 0, ','); // Pengurangan oleh 4 karena kami baru saja menambahkan unit lain ke array. indeks - = 4; } return array.join ('') + decimalPart; };
Aki143S
Terima kasih Pak. Inilah yang saya butuhkan.
Amir Hossein Ahmadi
11

Gunakan kode ini untuk menangani format mata uang untuk india. Kode negara dapat diubah untuk menangani mata uang negara lain.

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

// Use it.

formatter.format(amount);

keluaran:

3,50,256.95
Bathri Nathan
sumber
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban. Baca ini .
Shanteshwar Inde
@ShanteshwarInde saya akan menambahkan konteks tambahan untuk meningkatkan jawaban yakin
Bathri Nathan
11

Anda juga dapat menggunakan konstruktor Intl.NumberFormat . Inilah cara Anda dapat melakukannya.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 
Oliver
sumber
simpul js ini tidak berfungsi. Itu tidak memberikan respons dalam format India
Suraj Dalvi
7

Saya menulis yang ini sebelum menemukan posting ini. Tidak ada regex dan Anda benar-benar dapat memahami kode tersebut.

$(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>

Ronnie Overby
sumber
1
Saya menambahkan s.toString () di awal fungsi sehingga dapat menerima angka juga, bukan hanya string. Ini adalah jawaban yang saya pilih karena ini dapat dibaca, ringkas, dan tidak memiliki bug yang tampaknya dimiliki oleh jawaban regex.
FeFiFoFu
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: Fungsi ini hanya berfungsi dengan angka positif. untuk exmaple:

var number = -123123231232;
formatNumber(number)

Output: "123,123,231,232"

Tetapi untuk menjawab pertanyaan di atas toLocaleString()metode hanya memecahkan masalah.

var number = 123123231232;
    number.toLocaleString()

Output: "123,123,231,232"

Bersorak!

Kiry Meas
sumber
1
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Donald Duck
1
Skrip yang bagus, tetapi tidak bekerja dengan angka negatif.
Ralph David Abernathy
7

Jawaban saya adalah satu-satunya jawaban yang sepenuhnya menggantikan jQuery dengan alternatif yang jauh lebih masuk akal:

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

Solusi ini tidak hanya menambahkan koma, tetapi juga membulatkan ke sen terdekat jika Anda memasukkan jumlah seperti $(1000.9999)Anda akan mendapatkan $ 1,001.00. Selain itu, nilai yang Anda masukkan dapat dengan aman berupa angka atau string; itu tidak masalah.

Jika Anda berurusan dengan uang, tetapi tidak ingin tanda dolar terkemuka ditampilkan pada jumlah, Anda juga dapat menambahkan fungsi ini, yang menggunakan fungsi sebelumnya tetapi menghilangkan $:

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

Jika Anda tidak berurusan dengan uang, dan memiliki beragam persyaratan pemformatan desimal, inilah fungsi yang lebih fleksibel:

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

Oh, dan omong-omong, fakta bahwa kode ini tidak berfungsi di beberapa versi lama Internet Explorer sepenuhnya disengaja. Saya mencoba untuk menghancurkan IE kapan saja saya dapat menangkapnya tidak mendukung standar modern.

Harap ingat bahwa pujian yang berlebihan, di bagian komentar, dianggap di luar topik. Sebagai gantinya, cukup beri aku suara.

Lonnie Best
sumber
1
Angka (n) .toLocaleString () tampaknya merupakan jawaban terbaik tetapi Anda mungkin ingin menggunakan sesuatu seperti format Intl.NumberFormat ('en-US'). (N) daripada menghapus tanda dolar dan desimal jika semua yang diinginkan pengguna adalah koma dalam jumlah mereka.
bmacnaughton
@ bmacnaughton: Itu poin bagus ketika Anda tidak berurusan dengan uang. Namun, jika Anda berurusan dengan uang, dan hanya "tidak ingin tanda dolar terkemuka", Nomor (1000,50). ToLocaleString () menghasilkan '1.000,5', yang menghilangkan nol tidak signifikan yang biasanya disimpan ketika menampilkan nilai uang. Namun komentar yang baik: semua orang harus tahu apa yang Anda katakan.
Lonnie Best
6

Bagi saya, jawaban terbaik adalah menggunakan toLocaleString seperti yang dikatakan beberapa anggota. Jika Anda ingin memasukkan simbol '$', tambahkan saja languaje dan ketik opsi. Berikut adalah dan contoh untuk memformat angka ke Peso Meksiko

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

jalan pintas

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
Carlos A. Ortiz
sumber
5

Biarkan saya mencoba untuk meningkatkan uKolka 's jawaban dan mungkin bantuan orang lain menghemat waktu.

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

Anda harus menggunakan Number.prototype.toLocaleString () hanya jika kompatibilitas browsernya tidak menjadi masalah.

Beder Acosta Borges
sumber
ini mengilhami saya untuk menginstal numeral
npmeral
5

Cara alternatif, mendukung desimal, pemisah dan negatif yang berbeda.

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

Beberapa koreksi oleh @Jignesh Sanghani, jangan lupa untuk mengunggah komentarnya.

Felipe Buccioni
sumber
Sempurna untuk saya, baru saja menambahkan baris baru untuk menghapus pemformatan sebelum diproses.
Dennis Heiden
2
fn.substr(0, i)ganti dengan n.substr(0, i)dan juga number.toFixed(dp).split('.')[1]ganti dengan parseFloat(number).toFixed(dp).split('.')[1]. karena ketika saya menggunakan langsung itu memberi saya kesalahan. perbarui kode Anda
Jignesh Sanghani
cacat. jumlahnya bertambah. panggilan teladan akan sangat bagus!
mmm
beralih ceil ke lantai memperbaiki itu tetapi tidak yakin apa masalah lain akan muncul.
mmm
1
Coba Math.floor (-75.1);)
mmm
4

Saya pikir fungsi ini akan menangani semua masalah yang terkait dengan masalah ini.

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;
}
AbhinavRanjan
sumber
4

Hanya untuk Googler masa depan (atau tidak harus 'Googler'):

Semua solusi yang disebutkan di atas sangat bagus, namun, RegExp mungkin merupakan hal yang sangat buruk untuk digunakan dalam situasi seperti itu.

Jadi, ya, Anda dapat menggunakan beberapa opsi yang diusulkan atau bahkan menulis sesuatu yang primitif namun bermanfaat seperti:

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

Regexp yang digunakan di sini cukup sederhana dan perulangan akan berjalan tepat berapa kali yang dibutuhkan untuk menyelesaikan pekerjaan.

Dan Anda mungkin mengoptimalkannya jauh lebih baik, kode "KERING" & sebagainya.

Namun,

(-1234567.0987).toLocaleString();

(dalam kebanyakan situasi) akan menjadi pilihan yang jauh lebih baik.

Intinya bukan dalam kecepatan eksekusi atau kompatibilitas lintas-browser.

Dalam situasi ketika Anda ingin menunjukkan angka yang dihasilkan kepada pengguna, metode .toLocaleString () memberi Anda kekuatan super untuk berbicara bahasa yang sama dengan pengguna situs web atau aplikasi Anda (apa pun bahasanya).

Metode ini menurut dokumentasi ECMAScript diperkenalkan pada tahun 1999, dan saya percaya bahwa alasannya adalah harapan bahwa Internet pada suatu saat akan menghubungkan orang-orang di seluruh dunia, jadi, beberapa alat "internalisasi" diperlukan.

Hari ini Internet memang menghubungkan kita semua, jadi, penting untuk diingat bahwa dunia adalah cara yang lebih kompleks yang dapat kita bayangkan & bahwa (hampir) kita semua ada di sini , di Internet.

Jelas, mengingat keragaman orang, tidak mungkin untuk menjamin UX yang sempurna untuk semua orang karena kami berbicara bahasa yang berbeda, menghargai hal-hal yang berbeda, dll. Dan justru karena ini, bahkan lebih penting untuk mencoba melokalkan hal-hal sebanyak mungkin .

Jadi, mengingat ada beberapa standar khusus untuk representasi tanggal, waktu, angka, dll. & Bahwa kami memiliki alat untuk menampilkan hal-hal tersebut dalam format yang disukai oleh pengguna akhir, bukankah itu jarang dan hampir tidak bertanggung jawab untuk tidak gunakan alat itu (terutama dalam situasi ketika kita ingin menampilkan data ini kepada pengguna)?

Bagi saya, menggunakan RegExp alih-alih .toLocaleString () dalam situasi seperti itu terdengar sedikit seperti membuat aplikasi jam dengan JavaScript & mengkodekannya sedemikian rupa sehingga hanya akan menampilkan waktu Praha (yang akan sangat tidak berguna untuk orang yang tidak tinggal di Praha) meskipun perilaku default

new Date();

adalah mengembalikan data sesuai dengan jam pengguna akhir.

Igor Bykov
sumber
mengapa Anda menulis fungsi dengan const dan =>?
OG Sean
@OGSean selalu saya lakukan karena ini adalah cara paling mudah untuk mendeklarasikan variabel & fungsi. Juga, saya pikir ini membantu menjaga kode lebih bersih & lebih pendek.
Igor Bykov
4

Saya benar biasa-ekspresi-satunya solusi bagi mereka cinta satu kalimat

Anda melihat para pemain yang antusias di atas? Mungkin Anda bisa bermain golf darinya. Inilah stroke saya.

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

Gunakan THIN SPACE (U + 2009) untuk pemisah ribuan, seperti yang dikatakan oleh Sistem Satuan Internasional dalam edisi kedelapan (2006) publikasi mereka " Brosur SI: Sistem Satuan Internasional (SI) " (Lihat §5.3 .4.). Edisi kesembilan (2019) menyarankan untuk menggunakan ruang untuk itu (Lihat §5.4.4.). Anda dapat menggunakan apa pun yang Anda inginkan, termasuk koma.


Lihat.

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


Bagaimana cara kerjanya?

Untuk bagian integer

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") Masukkan "Aku"
    • /……/g di masing-masing
      • \B di antara dua digit yang berdekatan
        • (?=……)LOOKAHEAD POSITIF yang bagian kanannya adalah
          • (\d{3})+ satu atau lebih potongan tiga digit
          • \b diikuti oleh non-digit, seperti, titik, akhir string, dan lain-lain,
        • (?<!……)LOOKBEHIND NEGATIF tidak termasuk yang bagian kirinya
          • \.\d+ adalah titik yang diikuti oleh angka ("memiliki pemisah desimal").

Untuk bagian desimal

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") Masukan "F"
    • /……/g di masing-masing
      • \B di antara dua digit yang berdekatan
        • (?<=……)LOOKBEHIND POSITIF yang bagian kirinya adalah
          • \. pemisah desimal
          • (\d{3})+ diikuti oleh satu atau lebih potongan tiga digit.

Kelas karakter dan batasan

\d

Cocok dengan angka apa saja (angka Arab). Setara dengan [0-9].

Sebagai contoh,

  • /\d/atau /[0-9]/cocok 2dengan B2 is the suite number.

\b

Cocok dengan batas kata . Ini adalah posisi di mana karakter kata tidak diikuti atau didahului oleh karakter-kata lain, seperti antara huruf dan spasi. Perhatikan bahwa batas kata yang cocok tidak termasuk dalam pertandingan. Dengan kata lain, panjang batas kata yang cocok adalah nol.

Contoh:

  • /\bm/cocok dengan mdi moon;
  • /oo\b/tidak sesuai dengan oodi moon, karena oodiikuti oleh nyang merupakan karakter kata;
  • /oon\b/cocok dengan oondi moon, karena oonadalah akhir dari string, sehingga tidak diikuti oleh karakter kata;
  • /\w\b\w/ tidak akan pernah cocok dengan apa pun, karena karakter kata tidak pernah dapat diikuti oleh karakter non-kata dan kata.

\B

Cocok dengan batas non-kata . Ini adalah posisi di mana karakter sebelumnya dan berikutnya dari jenis yang sama: baik keduanya harus kata-kata, atau keduanya harus bukan kata-kata. Seperti antara dua huruf atau antara dua spasi. Awal dan akhir string dianggap bukan kata-kata. Sama seperti batas kata yang cocok, batas non-kata yang cocok juga tidak termasuk dalam pertandingan.

Sebagai contoh,

  • /\Bon/cocok ondi at noon;
  • /ye\B/cocok yedi possibly yesterday.

Kompatibilitas browser

Константин Ван
sumber
3

Saya menambahkan tofixed ke solusi Aki143S . Solusi ini menggunakan titik-titik untuk ribuan pemisah dan koma untuk presisi.

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

Contoh;

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

Sudah banyak jawaban bagus. Ini satu lagi, hanya untuk bersenang-senang:

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] : "");
}

Beberapa contoh:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"
Wayne
sumber
ini tidak bekerja dengan format(-123456)itu memberi-,123,456
wrossmck
1
Memperbaiki (meskipun mungkin ada cara yang lebih elegan untuk melakukannya tanpa memeriksa tanda setiap waktu). Bagaimanapun, pembaruan membuat ini berfungsi dengan angka negatif.
Wayne