2012-02-27 14 views
66

Devo mostrare un valore di valuta nel formato di 1K uguale a mille, o 1.1K, 1.2K, 1.9K ecc., Se non è pari a migliaia, altrimenti se meno di mille, viene visualizzato normale 500, 100, 250 ecc., Usando javascript per formattare il numero?Come formattare un numero di 2.5K se mille o più, altrimenti 900 in javascript?

+0

Avete bisogno anche di '' M' e G '? –

+0

Avrò bisogno di M sì ... Potete aiutarmi? –

+2

vedere http://stackoverflow.com/questions/17633462/format-a-javascript-number-with-a-metric-prefix-like-1-5k-1m-1g-etc – magritte

risposta

104

Suona come questo dovrebbe funzionare per voi:

function kFormatter(num) { 
    return num > 999 ? (num/1000).toFixed(1) + 'k' : num 
} 

console.log(kFormatter(1200)); 
console.log(kFormatter(900)); 
+0

NICE !!!! 4min fino contrassegnati come risposta. Grazie :) –

+0

Ama l'operatore ternario, breve pulito e conciso. –

+1

Piccola correzione suggerita ... Dovrebbe essere k minuscola per migliaia. La tomaia è per Kilos.Provato a modificare, ma richiede almeno 6 caratteri modificati prima che occorrerà. –

105

Una versione più generalizzata:

function nFormatter(num, digits) { 
 
    var si = [ 
 
    { value: 1, symbol: "" }, 
 
    { value: 1E3, symbol: "k" }, 
 
    { value: 1E6, symbol: "M" }, 
 
    { value: 1E9, symbol: "G" }, 
 
    { value: 1E12, symbol: "T" }, 
 
    { value: 1E15, symbol: "P" }, 
 
    { value: 1E18, symbol: "E" } 
 
    ]; 
 
    var rx = /\.0+$|(\.[0-9]*[1-9])0+$/; 
 
    var i; 
 
    for (i = si.length - 1; i > 0; i--) { 
 
    if (num >= si[i].value) { 
 
     break; 
 
    } 
 
    } 
 
    return (num/si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol; 
 
} 
 

 
/* 
 
* Tests 
 
*/ 
 
var tests = [ 
 
    { num: 1234, digits: 1 }, 
 
    { num: 100000000, digits: 1 }, 
 
    { num: 299792458, digits: 1 }, 
 
    { num: 759878, digits: 1 }, 
 
    { num: 759878, digits: 0 }, 
 
    { num: 123, digits: 1 }, 
 
    { num: 123.456, digits: 1 }, 
 
    { num: 123.456, digits: 2 }, 
 
    { num: 123.456, digits: 4 } 
 
]; 
 
var i; 
 
for (i = 0; i < tests.length; i++) { 
 
    console.log("nFormatter(" + tests[i].num + ", " + tests[i].digits + ") = " + nFormatter(tests[i].num, tests[i].digits)); 
 
}

+1

Qualcosa non va .. nFormatter (759878, 1) //759.9k nFormatter (759878, 0) // 76k – Switch

+0

@switch c'era un difetto nella mia regex, corretto. –

+0

@SalmanA - Ottimo aiuto, fallisce se si passa arg come stringa, se cleanse con parseFloat funziona bene. Grazie! –

49

Migliorare ulteriormente risposta di Salman perché restituisce nFormatter (33000) come 33,0 K

function nFormatter(num) { 
    if (num >= 1000000000) { 
     return (num/1000000000).toFixed(1).replace(/\.0$/, '') + 'G'; 
    } 
    if (num >= 1000000) { 
     return (num/1000000).toFixed(1).replace(/\.0$/, '') + 'M'; 
    } 
    if (num >= 1000) { 
     return (num/1000).toFixed(1).replace(/\.0$/, '') + 'K'; 
    } 
    return num; 
} 

ora nFormatter (33000) = 33K

+1

Ad ogni modo per fare ciò senza arrotondare il numero? 1.590.000 restituiranno 1,6 milioni. –

+0

@BrettHardin Si potrebbe fare 'toFixed (2)' o 'toFixed (3)' ... –

+2

A volte è difficile sapere quando postare una nuova risposta di modifica di uno esistente, qualcosa che uso per decidere è se rubo il codice da una risposta di altri utenti, di solito modifico la loro risposta in modo che possano ottenere il riconoscimento invece di rubare il loro codice. –

3

Migliorare ulteriormente @ risposta di Yash con il supporto numero negativo:

function nFormatter(num) { 
    isNegative = false 
    if (num < 0) { 
     isNegative = true 
    } 
    num = Math.abs(num) 
    if (num >= 1000000000) { 
     formattedNumber = (num/1000000000).toFixed(1).replace(/\.0$/, '') + 'G'; 
    } else if (num >= 1000000) { 
     formattedNumber = (num/1000000).toFixed(1).replace(/\.0$/, '') + 'M'; 
    } else if (num >= 1000) { 
     formattedNumber = (num/1000).toFixed(1).replace(/\.0$/, '') + 'K'; 
    } else { 
     formattedNumber = num; 
    } 
    if(isNegative) { formattedNumber = '-' + formattedNumber } 
    return formattedNumber; 
} 

nFormatter(-120000) 
"-120K" 
nFormatter(120000) 
"120K" 
+1

A volte è difficile sapere quando pubblicare una nuova risposta di modifica di una esistente, cosa che uso per decidere è se rubo il codice da una risposta di altri utenti, di solito modifico la loro risposta in modo che possano ottenere il riconoscimento invece di rubare il loro codice. –

14
/** 
* Shorten number to thousands, millions, billions, etc. 
* http://en.wikipedia.org/wiki/Metric_prefix 
* 
* @param {number} num Number to shorten. 
* @param {number} [digits=0] The number of digits to appear after the decimal point. 
* @returns {string|number} 
* 
* @example 
* // returns '12.5k' 
* shortenLargeNumber(12543, 1) 
* 
* @example 
* // returns '-13k' 
* shortenLargeNumber(-12567) 
* 
* @example 
* // returns '51M' 
* shortenLargeNumber(51000000) 
* 
* @example 
* // returns 651 
* shortenLargeNumber(651) 
* 
* @example 
* // returns 0.12345 
* shortenLargeNumber(0.12345) 
*/ 
function shortenLargeNumber(num, digits) { 
    var units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'], 
     decimal; 

    for(var i=units.length-1; i>=0; i--) { 
     decimal = Math.pow(1000, i+1); 

     if(num <= -decimal || num >= decimal) { 
      return +(num/decimal).toFixed(digits) + units[i]; 
     } 
    } 

    return num; 
} 

Thx @Cos per il commento, ho rimosso Math.round10 dipendenza.

+1

Trovo che la tua soluzione sia la più elegante, tuttavia quella rotonda10 la rovina per me. – Cos

+0

È possibile modificare il se in 'Math.abs (num)> = decimale'. –

1

Questo post è piuttosto vecchio ma in qualche modo ho raggiunto questo post cercando qualcosa. COSÌ per aggiungere il mio input Numeral js è la soluzione one stop ora un giorno. Si dà un gran numero di metodi per aiutare la formattazione dei numeri

http://numeraljs.com/

+1

numeraljs non viene più mantenuto. Il fork più attivo sembra essere [numbro] (https://github.com/foretagsplatsen/numbro). Ma nessuno dei due supporta la notazione SI/metrica –

3

È possibile utilizzare il pacchetto d3-format modellato Python corda formattazione PEP3101:

var f = require('d3-format') 
console.log(f.format('.2s')(2500)) // displays "2.5k" 
+0

Molto interessante. Sembra molto più pulito della mia soluzione originale. Grazie. –

22

Ecco una soluzione semplice che evita tutte le if dichiarazioni (con la potenza di Math).

var SI_PREFIXES = ["", "k", "M", "G", "T", "P", "E"]; 

function abbreviateNumber(number){ 

    // what tier? (determines SI prefix) 
    var tier = Math.log10(number)/3 | 0; 

    // if zero, we don't need a prefix 
    if(tier == 0) return number; 

    // get prefix and determine scale 
    var prefix = SI_PREFIXES[tier]; 
    var scale = Math.pow(10, tier * 3); 

    // scale the number 
    var scaled = number/scale; 

    // format number and add prefix as suffix 
    return scaled.toFixed(1) + prefix; 
} 
+0

Questo è un approccio più elegante e ho bisogno di iniziare a utilizzare matematicamente di più nella programmazione di sicuro. –

+0

@JasonSebring grazie! –

+0

Mi piace molto la tua soluzione. Per poter abbreviare anche i valori negativi, moltiplico il numero per -1 prima e dopo aver determinato il livello, poiché Math.log10 (valore negativo) restituirebbe NaN. – xdn

7

dare credito a Waylon Flinn se vi piace questo

Questo è stato migliorato dal suo approccio più elegante per gestire i numeri negativi e caso" 0,0" .

Meno cicli e "se" casi avete, meglio IMO.

function abbreviateNumber(number) { 
    var SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"]; 
    var tier = Math.log10(Math.abs(number))/3 | 0; 
    if(tier == 0) return number; 
    var postfix = SI_POSTFIXES[tier]; 
    var scale = Math.pow(10, tier * 3); 
    var scaled = number/scale; 
    var formatted = scaled.toFixed(1) + ''; 
    if (/\.0$/.test(formatted)) 
     formatted = formatted.substr(0, formatted.length - 2); 
    return formatted + postfix; 
} 

jsFiddle con casi di test ->https://jsfiddle.net/xyug4nvz/7/

+0

Grazie per aver risolto tutti i miei bug. : D –

+0

C'è ancora un bug fastidioso: 'abbreviateNumber (999999) == '1000k'' anziché' '1M''. Questo perché 'toFixed()' arrotonda anche i numeri. Non so come risolverlo, però: / –

0

Aggiunta alla risposta superiore, questo darà 1k per 1000 invece di 1.0K

function kFormatter(num) { 
    return num > 999 ? num % 1000 === 0 ? (num/1000).toFixed(0) + 'k' : (num/1000).toFixed(1) + 'k' : num 
} 
Problemi correlati