Hoe een nummer afdrukken met komma’s als duizenden scheiders in Javascript

Ik probeer een geheel getal in Javascript met komma’s als duizenden scheiders af te drukken. Ik wil bijvoorbeeld het nummer 1234567 zien als “1.234,567”. Hoe zou ik dit doen?

Hier is hoe ik het doe:

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

Is er een eenvoudiger of elegante manier om het te doen? Het zou leuk zijn als het ook met drijvers werkt, maar dat is niet nodig. Het hoeft geen locale-specifiek te zijn om te beslissen tussen perioden en komma’s.


1, Autoriteit 100%

Ik heb het idee van Kerry’s antwoord gebruikt, maar vereenvoudigde het omdat ik gewoon op zoek was naar iets eenvoudigs voor mijn specifieke doel. Dit is wat ik deed:

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

2, Autoriteit 70%

Ik ben verrast dat niemand noemde nummer. prototype.tolocalestring .
Het wordt geïmplementeerd in JavaScript 1.5 (die in 1999 werd geïntroduceerd), dus het wordt in principe ondersteund in alle belangrijke browsers.

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

Het werkt ook in Node.js vanaf v0.12 via opname van intl

Als je iets anders wilt, cijfer.js is misschien interessant.


3, Autoriteit 11%

Hieronder staan ​​twee verschillende browser-API’s die -nummers in gestructureerde -snaren kunnen transformeren . Houd er rekening mee dat niet alle machines van gebruikers een locale die komma’s in cijfers gebruikt . Om komma’s aan de uitgang te handhaven, kan elke “Western” Locale worden gebruikt, zoals en-US

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

⚠️ Mind dat Javascript een Maximaal geheel getal WAARDE VAN 9007199254740991


tolocalestring

// default behaviour on a machine with a local that uses commas for numbers
number.toLocaleString(); // "1,234,567,890"
// With custom settings, forcing a "US" locale to guarantee commas in output
var number2 = 1234.56789; // floating point example
number2.toLocaleString('en-US', {maximumFractionDigits:2}) // "1,234.57"

NumberFormat

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

Van wat ik heb gecontroleerd (tenminste Firefox) zijn ze beide min of meer hetzelfde wat betreft prestaties.

Live demo: https://codepen.io /vsync/pen/MWjdbgL?editors=1000


Antwoord 4, autoriteit 4%

Ik raad aan om number_format()

van phpjs.org te gebruiken

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

Mensen melden dat dit niet werkt zoals verwacht, dus ik deed een JS Fiddle dat inclusief geautomatiseerde tests.

Update 26/11/2017

Hier is die viool als stapelfragment met een enigszins gewijzigde uitvoer:

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

Antwoord 5, autoriteit 2%

Dit is een variatie op het antwoord van @mikez302, maar aangepast om getallen met decimalen te ondersteunen (volgens de feedback van @neu-rah dat numberWithCommas(12345.6789) -> “12.345.6.789” in plaats van “12.345.6789”

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

Antwoord 6, autoriteit 2%

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

Antwoord 7, autoriteit 2%

Reguliere expressie gebruiken

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

ToLocaleString() gebruiken

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

Intl.NumberFormat() gebruiken

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 HIER

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

Antwoord 8

Intl.NumberFormat

Native JS-functie. Ondersteund door IE11, Edge, nieuwste Safari, Chrome, Firefox, Opera, Safari op iOS en Chrome op Android.

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

Antwoord 9

Ik ben behoorlijk onder de indruk van het aantal antwoorden op deze vraag. Ik vind het antwoord van uKolkaleuk:

n.toLocaleString()

Maar helaas werkt het in sommige landen, zoals het Spaans, niet (IMHO) zoals verwacht voor getallen onder de 10.000:

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

Geeft 1000en niet 1.000.

Zie toLocaleString werkt niet op nummers minder dan 10000 in alle browsersom te weten waarom.

Dus ik moest het antwoord gebruiken door Elias Zamariahet juiste scheidingsteken voor duizendtallen te kiezen:

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

Deze werkt goed als one-liner voor beide landen die ,of .als scheidingsteken voor duizendtallen en begint in alle gevallen vanaf 1.000.

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

Geeft 1.000met een Spaanse landinstellingscontext.

Als je absolute controle wilt hebben over de manier waarop een getal wordt opgemaakt, kun je ook het volgende proberen:

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)

Geeft 1,234.57.

Deze heeft geen reguliere expressie nodig. Het werkt door het getal aan te passen aan het gewenste aantal decimalen met eerst toFixeden vervolgens te delen rond de komma .als die er is. De linkerkant wordt vervolgens omgezet in een reeks cijfers die wordt omgekeerd. Vervolgens wordt vanaf het begin om de drie cijfers een scheidingsteken voor duizendtallen toegevoegd en wordt het resultaat weer omgekeerd. Het uiteindelijke resultaat is de vereniging van de twee delen. Het teken van het ingevoerde getal wordt eerst met Math.absverwijderd en indien nodig teruggeplaatst.

Het is geen one-liner, maar niet veel langer en gemakkelijk om te zetten in een functie. Er zijn variabelen toegevoegd voor de duidelijkheid, maar deze kunnen worden vervangen door hun gewenste waarden als ze van tevoren bekend zijn. U kunt de uitdrukkingen gebruiken die toLocaleStringgebruiken om de juiste tekens voor de decimale komma en het scheidingsteken voor duizendtallen voor de huidige landinstelling te vinden (houd er rekening mee dat hiervoor een moderner Javascript vereist is.)


Antwoord 10

Iedereen bedankt voor hun antwoorden. Ik heb op basis van enkele van de antwoorden een meer “one-size-fits-all” oplossing gemaakt.

Het eerste fragment voegt een functie toe die PHP‘s number_format()nabootst Nummer prototype. Als ik een getal opmaak, wil ik meestal decimalen, dus de functie neemt het aantal decimalen in beslag dat moet worden weergegeven. Sommige landen gebruiken komma’s als decimaalteken en decimalen als het scheidingsteken voor duizendtallen, dus de functie maakt het mogelijk deze scheidingstekens in te stellen.

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

U zou dit als volgt gebruiken:

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

Ik ontdekte dat ik het getal vaak terug moest krijgen voor wiskundige bewerkingen, maar parseFloat converteert 5.000 naar 5, door simpelweg de eerste reeks gehele getallen te nemen. Dus ik heb mijn eigen float-conversiefunctie gemaakt en deze toegevoegd aan het String-prototype.

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

Nu kunt u beide functies als volgt gebruiken:

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

Antwoord 11

Ik denk dat dit de kortste reguliere expressie is die het doet:

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

Ik heb het op een paar cijfers gecontroleerd en het werkte.


Antwoord 12

Number.prototype.toLocaleString()zou geweldig zijn geweest als het standaard door alle browsers werd aangeboden (Safari).

Ik heb alle andere antwoorden gecontroleerd, maar niemand leek ze te polyfillen. Hier is een poging daartoe, wat eigenlijk een combinatie is van de eerste twee antwoorden; als toLocaleStringwerkt, gebruikt het het, als het niet werkt, gebruikt het een aangepaste functie.

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

Antwoord 13

Het scheidingsteken voor duizendtallen kan op een internationaal vriendelijke manier worden ingevoegd met behulp van het Intl-object van de browser:

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

Zie MDN’s artikel over NumberFormatvoor meer informatie. locale gedrag of standaard naar de gebruiker. Dit is een beetje meer waterdicht omdat het lokale verschillen respecteert; veel landen gebruiken punten om cijfers te scheiden, terwijl een komma de decimalen aangeeft.

Intl.NumberFormat is nog niet in alle browsers beschikbaar, maar het werkt in de nieuwste Chrome, Opera, & D.W.Z. De volgende release van Firefox zou dit moeten ondersteunen. Webkit lijkt geen tijdlijn te hebben voor implementatie.


Antwoord 14

U kunt deze procedure gebruiken om uw benodigde valuta op te maken.

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

Voor meer informatie kun je deze link openen.

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


Antwoord 15

Als je veel met valutawaarden werkt en veel formatteert, is het misschien de moeite waard om kleine accounting.jstoe te voegen die veel randgevallen en lokalisatie afhandelt:

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

Antwoord 16

De volgende code gebruikt char scan, dus er is geen 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] : ''); 
}

Het laat veelbelovende prestaties zien: http://jsperf.com/number-formatting-with -komma’s/5

2015.4.26: Kleine oplossing om het probleem op te lossen wanneer num<0. Zie https://jsfiddle.net/runsun/p5tqqvs3/


Antwoord 17

Hier is een eenvoudige functie die komma’s invoegt voor duizend scheidingstekens. Het gebruikt arrayfuncties in plaats van een 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('');
};

CodeSandbox-link met voorbeelden: https://codesandbox.io/s/p38k63w0vq


Antwoord 18

Gebruik deze code om de valutanotatie voor India te verwerken. De landcode kan worden gewijzigd om de valuta van een ander land te verwerken.

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

uitvoer:

3,50,256.95

Antwoord 19

Mijn antwoord is het enige antwoord dat jQuery volledig vervangt door een veel verstandiger alternatief:

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

Deze oplossing voegt niet alleen komma’s toe, maar rondt ook af op de dichtstbijzijnde cent. Als u een bedrag invoert zoals $(1000.9999), krijgt u $1.001.00. Bovendien kan de waarde die u invoert veilig een getal of een tekenreeks zijn; het maakt niet uit.

Als u te maken hebt met geld, maar niet wilt dat een toonaangevend dollarteken dat wordt weergegeven op het bedrag, kunt u deze functie ook toevoegen, die de vorige functie gebruikt, maar verwijdert de $:

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

Als u niet omgaat met geld, en een variërende decimale formatteringsvereisten hebt, is hier een veelzijdige functie:

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, en trouwens, het feit dat deze code niet werkt in een oude versie van Internet Explorer is volledig opzettelijk. Ik probeer te breken, dwz op elk moment dat ik het kan vangen, het niet ondersteunen van moderne normen.

Houd er rekening mee dat buitensporige lof, in het opmerkingsgedeelte, wordt beschouwd als off-thema. In plaats daarvan douchen me gewoon met up-stemmen.


20

Ik heb deze geschreven voordat ik op dit bericht struikelde. Geen regex en u kunt de code daadwerkelijk begrijpen.

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

Antwoord 21

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

BEWERKEN:
De functie werkt alleen met een positief getal. bijvoorbeeld:

var number = -123123231232;
formatNumber(number)

Uitvoer: “123,123,231,232”

Maar om de bovenstaande vraag te beantwoorden, lost de methode toLocaleString()het probleem gewoon op.

var number = 123123231232;
    number.toLocaleString()

Uitvoer: “123,123,231,232”

Proost!


Antwoord 22

Laat me proberen uKolka‘s antwoorden misschien anderen helpen bespaar wat tijd.

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

Antwoord 23

Alleen voor toekomstige Googlers (of niet noodzakelijk ‘Googlers’):

Alle hierboven genoemde oplossingen zijn geweldig, maar RegExp kan in een dergelijke situatie erg slecht zijn om te gebruiken.

Dus, ja, je zou enkele van de voorgestelde opties kunnen gebruiken of zelfs iets primitiefs maar nuttigs kunnen schrijven, zoals:

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

De regexp die hier wordt gebruikt is vrij eenvoudig en de lus gaat precies het aantal keren dat nodig is om de klus te klaren.

En je zou het veel beter kunnen optimaliseren, “DRYify” code & enzovoort.

Toch,

(-1234567.0987).toLocaleString();

(in de meeste situaties) zou een veel betere keuze zijn.

Het gaat niet om de snelheid van uitvoering of compatibiliteit tussen browsers.

In situaties waarin u het resulterende getal aan de gebruiker wilt laten zien, geeft de .toLocaleString()-methode u de superkracht om dezelfde taal te spreken met de gebruiker van uw website of app (wat haar/zijn taal ook is).

p>

Deze methode is volgens ECMAScript-documentatie geïntroduceerd in 1999, en ik geloof dat de reden daarvoor de hoop was dat het internet op een gegeven moment mensen over de hele wereld met elkaar zal verbinden, dus er waren wat “internalisatie”-tools nodig.

Tegenwoordig verbindt internet ons allemaal, dus het is belangrijk om te onthouden dat de wereld veel complexer is dan we ons misschien kunnen voorstellen & dat (/bijna) wij allemaal hier zijn, op internet.

Het is duidelijk dat, gezien de diversiteit van mensen, het onmogelijk is om voor iedereen een perfecte UX te garanderen omdat we verschillende talen spreken, verschillende dingen waarderen, enz. En juist daarom is het nog belangrijker om dingen zoveel mogelijk te lokaliseren als het mogelijk is.

Dus, gezien het feit dat er een aantal specifieke normen zijn voor de weergave van datum, tijd, cijfers, enz. & dat we een tool hebben om die dingen weer te geven in het formaat dat de eindgebruiker de voorkeur heeft, is dat niet zeldzaam en bijna onverantwoordelijk om die tool niet te gebruiken (vooral in situaties waarin we deze gegevens aan de gebruiker willen tonen)?

Voor mij klinkt het gebruik van RegExp in plaats van .toLocaleString() in een dergelijke situatie een beetje als het maken van een klok-app met JavaScript & het zo hard coderen dat het alleen de Praagse tijd weergeeft (wat vrij nutteloos zou zijn voor mensen die niet in Praag wonen), ook al is het standaardgedrag van

new Date();

is om de gegevens te retourneren volgens de klok van de eindgebruiker.


Antwoord 24

Een alternatieve manier, met ondersteuning voor decimalen, verschillende scheidingstekens en negatieven.

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

Enkele correcties door @Jignesh Sanghani, vergeet niet zijn commentaar te upvoten.


Antwoord 25

Ik denk dat deze functie alle problemen met betrekking tot dit probleem zal oplossen.

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

26

Voor iedereen die van 1-liners en een enkele regex houdt, maar wil niet willen gebruiken Split (), hier is een verbeterde versie van de regex van andere antwoorden die handvatten (negeren) decimaal Plaatsen:

   var formatted = (x+'').replace(/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g, (digit, fract) => fract || digit + ',');

De regex eerst komt overeen met een substring die begint met een letterlijke “.” en vervangt het met zichzelf (“fract”) en komt vervolgens overeen met elk cijfer gevolgd door veelvouden van 3 cijfers en puts “,” erna.

Bijvoorbeeld, x = 12345678.12345678 geeft geformatteerd = ’12, 345.678.12345678 ‘.


27

Als u op zoek bent naar een korte en zoete oplossing:

const number = 12345678.99;
const numberString = String(number).replace(
    /^\d+/,
    number => [...number].map(
        (digit, index, digits) => (
            !index || (digits.length - index) % 3 ? '' : ','
        ) + digit
    ).join('')
);
// numberString: 12,345,678.99

28

Ik heb tofixed toegevoegd aan AKI143S -oplossing.
Deze oplossing gebruikt stippen voor duizenden scheiders en komma voor de precisie.

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

Voorbeelden;

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

Other episodes