Javascript, toFixed un decimale tranne quando è 0
Devo correggere un numero con decimali a solo 1 decimale, quindi ho provato questo:
const convert = (numberWithDecimal) => numberWithDecimal
.toFixed(1)
.replace('.', ',')
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
console.log(convert(123.123)); // "123,1" that's ok
console.log(convert(123.005)); // "123,0" that's NOT ok
Il codice è qui: https://jsfiddle.net/pmiranda/sp0fLrhb/3/ Ma, quando i decimali sono arrotondati a 0, non voglio usarlo, ad esempio:
In 123.005ho bisogno di ottenere 123, non123.0
Qualsiasi aiuto?
Risposte
L'intero scopo della .toFixedfunzione è garantire un numero fisso di cifre decimali, ad esempio quando si visualizza la valuta (spesso si visualizzano$25.00 instead of $25)
Se non vuoi un numero fisso di punti decimali (ad esempio, a volte vuoi 0 ea volte vuoi 1), allora non vuoi usare .toFixed. Prova invece a utilizzare la moltiplicazione e l'arrotondamento per ottenere il risultato desiderato:
const convert = (numberWithDecimal) => String(
Math.round(numberWithDecimal * 10) / 10
)
.replace(".", ",");
console.log(convert(123.123));
console.log(convert(123.005));
Una nota interessante sulla performance
Mi piace al profilo soluzioni quando possibile e sembrava a prima vista come la mia soluzione sarebbe più veloce (sto solo eseguendo qualche intero aritmetica, mentre si sta eseguendo molteplici funzioni stringa). Quindi ho scritto quanto segue:
var d0 = new Date();
for (var i = 0; i < 1000000; i++) { convert(123.123); }
console.log(new Date() - d0);
Ho quindi testato le nostre due soluzioni. Sulla mia macchina la tua soluzione ha funzionato circa il 15% più velocemente della mia. Non so perché, ma se sei interessato alle massime prestazioni, la tua soluzione di più .replace()catene in realtà è stata eseguita più velocemente (in Firefox su Mac OS X)
Nota 2 sulle prestazioni
Se scegli di utilizzare la Math.round()soluzione ma desideri che venga eseguita un po ' più velocemente, c'è un hack in JavaScript per arrotondare i numeri molto velocemente:
Math.round(123.123); // 123
Math.round(123.987); // 124
(123.123 + 0.5)|0; // 123
(123.987 + 0.5)|0; // 124
Nota che questo hack in realtà fallisce con numeri negativi. Ma fintanto che hai a che fare con numeri positivi, questo metodo è più veloce della chiamata Math.round()(e ottiene prestazioni alla pari con la tua soluzione
Funziona perché gli operatori bit a bit in JavaScript ( &, |, ^, ~) funzionano solo su interi valori. Se viene passato un numero non intero, tronceranno prima il valore (eliminando eventuali punti decimali). Dato che vogliamo arrotondare e non troncare, aggiungiamo 0,5 prima del troncamento.
Immagino che l'ovvia soluzione semplice sia aggiungere replace(',0','')alla catena.
const convert = (numberWithDecimal) => numberWithDecimal
.toFixed(1)
.replace('.', ',')
.replace(',0', '')
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
console.log(convert(123.123)); // "123,1" that's ok
console.log(convert(123.005)); // "123,1" that's ok