Pertanyaan Cara mencetak angka dengan koma sebagai ribuan pemisah di JavaScript


Saya mencoba mencetak bilangan bulat JavaScript dengan koma sebagai ribuan pemisah. Sebagai contoh, saya ingin menunjukkan nomor 1234567 sebagai "1,234,567". Bagaimana saya akan 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 itu bekerja dengan pelampung juga, tapi itu tidak perlu. Tidak perlu spesifik lokal untuk memutuskan antara titik dan koma.


1165
2018-05-24 23:42


asal


Jawaban:


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

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

Hanya ini yang benar-benar perlu Anda ketahui.

@Neils Bom bertanya bagaimana regex bekerja. Penjelasan saya agak panjang. Itu tidak akan cocok dengan komentar dan saya tidak tahu di mana lagi untuk meletakkannya sehingga saya melakukannya di sini. Jika ada yang punya saran lain untuk tempat meletakkannya, tolong beri tahu saya.

Regex menggunakan 2 pernyataan lookahead: yang positif untuk mencari titik dalam string yang memiliki kelipatan 3 digit berturut-turut setelahnya, dan pernyataan negatif untuk memastikan bahwa titik hanya memiliki kelipatan 3 digit. Ekspresi penggantian menempatkan koma di sana.

Misalnya, jika Anda meneruskannya "123456789.01", pernyataan positif akan cocok dengan setiap tempat di sebelah kiri 7 (karena "789" merupakan kelipatan 3 digit, "678" adalah kelipatan 3 digit, "567", dll.). Pernyataan negatif memeriksa bahwa kelipatan 3 digit tidak memiliki digit apa pun setelahnya. "789" memiliki periode setelah itu jadi itu tepat kelipatan 3 digit, jadi koma pergi ke sana. "678" adalah kelipatan 3 digit tetapi memiliki "9" setelahnya, jadi 3 digit itu adalah bagian dari grup 4, dan koma tidak pergi ke sana. Demikian pula untuk "567". "456789" adalah 6 digit, yang merupakan kelipatan 3, jadi koma berjalan sebelum itu. "345678" adalah kelipatan 3, tetapi memiliki "9" setelahnya, jadi tidak ada koma yang masuk ke sana. Dan seterusnya. The "\ B" membuat regex dari menempatkan 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 masalah, Anda dapat menggunakan fungsi ini:

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

2061
2018-05-25 00:40



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

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

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

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


1046
2017-07-15 21:01



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

 Pikiran bahwa javascript memiliki bilangan bulat maksimum Nilai dari 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 mengenai kinerja.


177
2017-08-22 08:52



Saya sarankan menggunakan phpjs.org's number_format ()

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

PERBARUI 02/13/14

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

Perbarui 26/11/2017

Berikut ini biola sebagai Cuplikan Stack dengan output sedikit diubah:

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


86
2018-05-24 23:47



Ini adalah variasi dari jawaban @ mikez302, tetapi dimodifikasi untuk mendukung angka dengan desimal (umpan balik per @ neu-rah yang numberWithCommas (12345.6789) -> "12,345.6,789" daripada "12,345.6789"

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

65
2018-06-05 15:03



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

54
2017-08-19 06:47



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

Cuplikan pertama menambahkan fungsi yang meniru PHP's number_format() ke prototipe Nomor. Jika saya memformat angka, saya biasanya menginginkan tempat desimal sehingga fungsi tersebut mengambil jumlah tempat desimal untuk ditampilkan. Beberapa negara menggunakan koma sebagai desimal dan desimal sebagai pemisah ribuan sehingga fungsi ini memungkinkan pemisah ini disetel.

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 angka kembali untuk operasi matematika, tetapi parseFloat mengkonversi 5.000 menjadi 5, cukup 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

31
2017-09-18 01:50



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

28
2017-10-31 23:56



Saya pikir ini adalah ekspresi reguler terpendek yang melakukannya:

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

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

Saya memeriksanya pada beberapa nomor dan itu berhasil.


22
2018-03-13 06:31



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

Aku memeriksa semua jawaban yang lain tetapi tidak ada yang tampak meng-polyfill-nya. Ini adalah sebuah poc menuju itu, yang sebenarnya merupakan kombinasi dari dua jawaban pertama; jika toLocaleString bekerja menggunakannya, jika tidak menggunakan fungsi kustom.

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


18
2018-05-19 05:11



Pemisah ribuan dapat disisipkan dengan cara ramah internasional menggunakan browser Intl obyek:

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 ke pengguna. Ini sedikit lebih mudah dipercaya karena menghormati 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 sepertinya tidak memiliki waktu untuk implementasi.


15
2018-04-26 01:43