¿Cómo formatear un número con comas como separadores de miles?
Estoy intentando imprimir un número entero en JavaScript con comas como separadores de miles. Por ejemplo, quiero mostrar el número 1234567 como "1.234.567". ¿Cómo haría para hacer esto?
Así es como lo estoy haciendo:
function numberWithCommas(x) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x))
x = x.replace(pattern, "$1,$2");
return x;
}
console.log(numberWithCommas(1000))
¿Existe una forma más sencilla o más elegante de hacerlo? Sería bueno que también funcionara con flotadores, pero eso no es necesario. No es necesario que sea específico de la región para decidir entre puntos y comas.
Utilicé la idea de la respuesta de Kerry, pero la simplifiqué ya que solo buscaba algo simple para mi propósito específico. Esto es lo que tengo:
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Mostrar fragmento de código
La expresión regular utiliza 2 afirmaciones anticipadas:
- uno positivo para buscar cualquier punto en la cadena que tenga un múltiplo de 3 dígitos seguidos después,
- una afirmación negativa para asegurarse de que ese punto solo tenga exactamente un múltiplo de 3 dígitos. La expresión de reemplazo pone una coma allí.
Por ejemplo, si lo pasa 123456789.01
, la afirmación positiva coincidirá con cada lugar a la izquierda del 7 (ya que 789
es múltiplo de 3 dígitos, 678
es múltiplo de 3 dígitos, 567
etc.). La afirmación negativa verifica que el múltiplo de 3 dígitos no tenga ningún dígito después. 789
tiene un punto después, por lo que es exactamente un múltiplo de 3 dígitos, por lo que va una coma allí. 678
es un múltiplo de 3 dígitos pero tiene un 9
después, por lo que esos 3 dígitos son parte de un grupo de 4 y la coma no va allí. De manera similar para 567
. 456789
tiene 6 dígitos, que es múltiplo de 3, por lo que va una coma antes. 345678
es un múltiplo de 3, pero tiene un 9
después, por lo que no va ninguna coma allí. Etcétera. Esto \B
evita que la expresión regular ponga una coma al principio de la cadena.
@ neu-rah mencionó que esta función agrega comas en lugares no deseados si hay más de 3 dígitos después del punto decimal. Si esto es un problema, puede utilizar esta función:
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
Mostrar fragmento de código
@tjcrowder señaló que ahora que JavaScript tiene búsqueda hacia atrás ( información de soporte ), se puede resolver en la propia expresión regular :
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
Mostrar fragmento de código
(?<!\.\d*)
es una mirada hacia atrás negativa que dice que la coincidencia no puede ir precedida por un .
seguido de cero o más dígitos. La mirada hacia atrás negativa es más rápida que la solución split
y ( comparación ), al menos en V8.join
Me sorprende que nadie haya mencionado Number.prototype.toLocaleString . Está implementado en JavaScript 1.5 (que se introdujo en 1999), por lo que básicamente es compatible con todos los principales navegadores.
var n = 34523453.345;
console.log(n.toLocaleString()); // "34,523,453.345"
También funciona en Node.js a partir de v0.12 mediante la inclusión de Intl
Si quieres algo diferente, Numeral.js puede resultar interesante.
A continuación se muestran dos API de navegador diferentes que pueden transformar números en cadenas estructuradas . Tenga en cuenta que no todas las máquinas de los usuarios tienen una configuración regional que utiliza comas entre números . Para imponer comas en la salida, se puede utilizar cualquier configuración regional "occidental" , comoen-US
let number = 1234567890; // Example number to be converted
⚠️ Tenga en cuenta que javascript tiene un valor entero máximo de9007199254740991
// default behaviour on a machine with a locale that uses commas for numbers
let number = 1234567890;
number.toLocaleString(); // "1,234,567,890"
// With custom settings, forcing a "US" locale to guarantee commas in output
let number2 = 1234.56789; // floating point example
number2.toLocaleString('en-US', {maximumFractionDigits:2}); // "1,234.57"
//You can also force a minimum of 2 trailing digits
let number3 = 1.5;
number3.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2}); //"1.50"
Formato numérico
let number = 1234567890;
let nf = new Intl.NumberFormat('en-US');
nf.format(number); // "1,234,567,890"
Por lo que verifiqué (al menos Firefox), ambos son más o menos iguales en cuanto a rendimiento.
⚡ Demostración en vivo : https://codepen.io/vsync/pen/MWjdbgL?editors=1000
Sugiero usar number_format() de phpjs.org
function number_format(number, decimals, dec_point, thousands_sep) {
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);
}
ACTUALIZACIÓN 13/02/14
La gente ha estado informando que esto no funciona como se esperaba, así que hice un JS Fiddle que incluye pruebas automatizadas.
Actualización 26/11/2017
Aquí está ese violín como un fragmento de pila con una salida ligeramente modificada:
function number_format(number, decimals, dec_point, thousands_sep) {
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;
}