Formatieren Sie eine Zahl als 2,5 KB, wenn tausend oder mehr, andernfalls 900

152

Ich muss einen Währungswert im Format 1K von eintausend oder 1,1K, 1,2K, 1,9K usw. anzeigen, wenn er nicht gerade Tausend ist, andernfalls, wenn er unter tausend liegt, werden normale 500, 100, 250 usw. Angezeigt Verwenden Sie Javascript, um die Nummer zu formatieren?

Carl Weis
quelle
2
Benötigen Sie auch Mund G?
Salman A
Ich brauche M ja ... Kannst du helfen?
Carl Weis

Antworten:

209

Klingt so, als ob dies für Sie funktionieren sollte:

function kFormatter(num) {
    return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)
}
    
console.log(kFormatter(1200)); // 1.2k
console.log(kFormatter(-1200)); // -1.2k
console.log(kFormatter(900)); // 900
console.log(kFormatter(-900)); // -900

Jake Feasel
quelle
2
Kleinere Korrektur vorgeschlagen ... Sollte für Tausende in Kleinbuchstaben k sein. Ober ist für Kilo. Versucht zu bearbeiten, erfordert jedoch mindestens 6 geänderte Zeichen, bevor es dauert.
Adam Youngers
Wie füge ich hier eine PHP-Variable ein und verwende sie? dh wenn meine Zahlenvariable ist, $mynumber_outputwo füge ich diese ein, um sie zu verwenden? Zum Beispiel, sagen wir $mynumber_output= 12846, ich möchte, dass 12846 um12.8k
Beachten Sie, dass ein Kilobyte in einigen Fällen 1024 Byte entspricht: en.wikipedia.org/wiki/Kilobyte
Olle Härstedt
Irgendeine Idee, wie wir 1000 als 1.0k anstelle von 1k anzeigen lassen können?
Brent
1
Beantwortet die Frage des Benutzers nicht vollständig. "Ich werde M ja brauchen ... Kannst du helfen?" - Carl Weis
tfmontague
216

Eine allgemeinere Version:

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

Salman A.
quelle
@SalmanA - Große Hilfe, es schlägt fehl, wenn ein Argument als String übergeben wird, wenn es mit parseFloat bereinigt funktioniert. Danke dir!
Adesh M
1
Kleine Korrektur für Zahlen unter <1000, addiere {Wert: 1E0, Symbol: ""} zu var si =
Dimmduh
1
@GiovanniAzua nur ersetzen if (num >= si[i].value)mitif (Math.abs(num) >= si[i].value)
Salman A
was macht .replace(rx, "$1")das
M. Octavio
1
@ M.Octavio der reguläre Ausdruck wird verwendet, um nachfolgende Nullen zu trimmen, z. B. 1.0wird 1und 1.10wird1.1
Salman A
78

Hier ist eine einfache Lösung, die alle ifAussagen vermeidet (mit der Kraft von Math).

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

function abbreviateNumber(number){

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

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

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

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

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

Bonus Meme

Wofür steht SI?

Waylon Flinn
quelle
Ihre Lösung gefällt mir sehr gut. Um auch negative Werte verkürzen zu können, multipliziere ich die Zahl vor und nach dem Bestimmen der Ebene mit -1, da Math.log10 (negativeValue) NaN zurückgeben würde.
Xhadon
Verwenden Sie einfach Math.abs, um negative Zahlen wie folgt zu unterstützen : var tier = Math.log10(Math.abs(number)) / 3 | 0;.
Caio Tarifa
70

Weitere Verbesserung von Salmans Antwort, da nFormatter (33000) als 33.0K zurückgegeben wird

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

jetzt nFormatter (33000) = 33K

Yash
quelle
2
Wie auch immer, ohne die Zahl zu runden? 1.590.000 werden 1,6 Millionen zurückgeben.
Brett Hardin
3
Manchmal ist es schwierig zu wissen, wann eine neue Antwort zum Bearbeiten einer vorhandenen Antwort zu veröffentlichen ist. Ich entscheide, ob ich den Code einer anderen Benutzerantwort stehle. Normalerweise bearbeite ich deren Antwort so, dass sie die Erkennung erhalten, anstatt dass ich ihre stehle Code.
MH
@Yash Sie sind der Code, den ich versuche, im Zählerskript zu implementieren, aber dies nicht zu bekommen, ist mein Codepen-Link codepen.io/Merajkhan/pen/MMoxGE?editors=1010 Können Sie mir helfen, wie ich diese gewünschte Logik implementieren kann ? K, L, M Einheiten müssen kommen.
Mehraj Khan
Toll. Kurze und süße Lösung.
Hasitha Jayawardana
22
/**
 * 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 für einen Kommentar, ich habe die Math.round10-Abhängigkeit entfernt.

Martin Sznapka
quelle
1
Sie können das if in ändern Math.abs(num) >= decimal.
Conor Pender
18

Viele Antworten in diesem Thread werden durch die Verwendung von mathematischen Objekten, Kartenobjekten, for-Schleifen, regulären Ausdrücken usw. ziemlich kompliziert. Diese Ansätze verbessern jedoch nicht wirklich die Lesbarkeit des Codes oder die Leistung. Ein direkter Ansatz scheint das beste Design zu bieten.

Barwert mit K formatieren

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3) return +(n / 1e3).toFixed(1) + "K";
};

console.log(formatCash(2500));

Barwert mit KMBT formatieren

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
  if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
  if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + "B";
  if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
};

console.log(formatCash(1235000));

Negative Zahlen verwenden

let format;
const number = -1235000;

if (number < 0) {
  format = '-' + formatCash(-1 * number);
} else {
  format = formatCash(number);
}
tfmontague
quelle
1
@Jan - Mein Beitrag wurde mit einem Beispiel aktualisiert, aber es war einfach genug, die negative Form mit'-' + formatCash(-1 * number)
tfmontague
15

Geben Sie Waylon Flinn Kredit, wenn Sie dies mögen

Dies wurde von seinem eleganteren Ansatz zum Umgang mit negativen Zahlen und ".0" -Fällen verbessert.

Je weniger Schleifen und "Wenn" -Fälle Sie haben, desto besser ist die 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 mit Testfällen -> https://jsfiddle.net/xyug4nvz/7/

Jason Sebring
quelle
1
Es gibt immer noch einen nervigen Fehler: abbreviateNumber(999999) == '1000k'statt '1M'. Dies liegt daran, dass toFixed()auch die Zahlen gerundet werden. Ich bin mir jedoch nicht sicher, wie
ich das Problem
@VitorBaptista Wenn toFixed()die Nummer trotzdem gerundet wird, können Sie die Nummer auch runden, bevor Sie sie an senden abbreviateNumber(), sodass sie 1Mstatt zurückgegeben wird 1000k. Keine Lösung, sondern eine Problemumgehung.
Forsureitsme
2
Wenn Sie keine Rundung wünschen, können Sie dies nach dem Skalierungsschritt tun:const floored = Math.floor(scaled * 10) / 10;
tybro0103
14

ES2020 bietet Unterstützung für die Intl.NumberFormatVerwendung der Notation wie folgt:

console.log(Intl.NumberFormat('en-US', { notation: "compact" , compactDisplay: "short" }).format(987654321));

NumberFormat Spezifikationen:

Beachten Sie, dass derzeit nicht alle Browser ES2020 unterstützen. Daher benötigen Sie möglicherweise diese Polyfill: https://formatjs.io/docs/polyfills/intl-numberformat

Ori Preis
quelle
Dieses Paket ist veraltet. Verwenden Sie daher diesen Link: npmjs.com/package/@formatjs/intl-numberformat
Ammad Khalid
2
Hinweis: Chrome unterstützt das notationund, compactDisplayaber FireFox 77 und Safari 13.1 unterstützen es immer noch nicht, sodass Sie wahrscheinlich die Polyfüllung benötigen.
Josh Unger
Wow, Firefox hat anscheinend gerade Unterstützung für Version 78 hinzugefügt. Natürlich wird dieser Kommentar in 2+ Jahren dumm aussehen. : P (Es ist zwar lustig für mich, weil der Code für mich ausgeführt wird, aber nicht richtig konvertiert wird, sodass ich ein Update durchführen muss.)
Andrew
11

das ist ziemlich elegant.

function formatToUnits(number, precision) {
  const abbrev = ['', 'k', 'm', 'b', 't'];
  const unrangifiedOrder = Math.floor(Math.log10(Math.abs(number)) / 3)
  const order = Math.max(0, Math.min(unrangifiedOrder, abbrev.length -1 ))
  const suffix = abbrev[order];

  return (number / Math.pow(10, order * 3)).toFixed(precision) + suffix;
}

formatToUnits(12345, 2)
==> "12.35k"
formatToUnits(0, 3)
==> "0.000"
Novellizator
quelle
3

Weitere Verbesserung der Antwort von @ Yash mit Unterstützung für negative Zahlen:

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"
Erdbeere
quelle
3

Dieser Beitrag ist ziemlich alt, aber ich habe diesen Beitrag irgendwie erreicht und nach etwas gesucht. SO, um meine Eingabe hinzuzufügen Numeral js ist jetzt die One-Stop-Lösung. Es gibt eine Vielzahl von Methoden zur Formatierung der Zahlen

http://numeraljs.com/

Vatsal
quelle
1
numeraljs wird nicht mehr gepflegt. Die aktivste Gabel scheint numbro zu sein . Aber keiner von ihnen unterstützt die SI / Metrik-Notation
Vincent de Lagabbe
2

Kurze und generische Methode

Sie können das COUNT_FORMATSKonfigurationsobjekt je nach dem von Ihnen getesteten Wertebereich so lang oder kurz machen, wie Sie möchten.

// Configuration    
const COUNT_FORMATS =
[
  { // 0 - 999
    letter: '',
    limit: 1e3
  },
  { // 1,000 - 999,999
    letter: 'K',
    limit: 1e6
  },
  { // 1,000,000 - 999,999,999
    letter: 'M',
    limit: 1e9
  },
  { // 1,000,000,000 - 999,999,999,999
    letter: 'B',
    limit: 1e12
  },
  { // 1,000,000,000,000 - 999,999,999,999,999
    letter: 'T',
    limit: 1e15
  }
];
    
// Format Method:
function formatCount(value)
{
  const format = COUNT_FORMATS.find(format => (value < format.limit));

  value = (1000 * value / format.limit);
  value = Math.round(value * 10) / 10; // keep one decimal number, only if needed

  return (value + format.letter);
}

// Test:
const test = [274, 1683, 56512, 523491, 9523489, 5729532709, 9421032489032];
test.forEach(value => console.log(`${ value } >>> ${ formatCount(value) }`));

Gil Epshtain
quelle
1

Wenn Sie die oberste Antwort hinzufügen, erhalten Sie 1k für 1000 anstelle von 1.0k

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

Eine modifizierte Version von Waylon Flinns Antwort mit Unterstützung für negative Exponenten:

function metric(number) {

  const SI_SYMBOL = [
    ["", "k", "M", "G", "T", "P", "E"], // +
    ["", "m", "μ", "n", "p", "f", "a"] // -
  ];

  const tier = Math.floor(Math.log10(Math.abs(number)) / 3) | 0;

  const n = tier < 0 ? 1 : 0;

  const t = Math.abs(tier);

  const scale = Math.pow(10, tier * 3);

  return {
    number: number,
    symbol: SI_SYMBOL[n][t],
    scale: scale,
    scaled: number / scale
  }
}

function metric_suffix(number, precision) {
  const m = metric(number);
  return (typeof precision === 'number' ? m.scaled.toFixed(precision) : m.scaled) + m.symbol;
}

for (var i = 1e-6, s = 1; i < 1e7; i *= 10, s *= -1) {
  // toggles sign in each iteration
  console.log(metric_suffix(s * (i + i / 5), 1));
}

console.log(metric(0));

Erwartete Ausgabe:

   1.2μ
 -12.0μ
 120.0μ
  -1.2m
  12.0m
-120.0m
   1.2
 -12.0
 120.0
  -1.2k
  12.0k
-120.0k
   1.2M
{ number: 0, symbol: '', scale: 1, scaled: 0 }
Thalionâth
quelle
1
  • Negative Zahl unterstützen
  • Überprüfung auf !Number.isFinite
  • Wechseln Sie ' K M G T P E Z Y'zu, ' K M'wenn Sie möchten, dass die maximale Einheit istM

Der folgende Code lautet 1K = 1024. Wenn Sie 1K = 1000 möchten, ändern Sie alle 1024 in 1000.


Number.prototype.prefix = function (precision = 2) {

    var units = ' K M G T P E Z Y'.split(' ');

    if (this < 0) {
        return '-' + Math.abs(this).prefix(precision);
    }

    if (this < 1) {
        return this + units[0];
    }

    var power = Math.min(
        Math.floor(Math.log(this) / Math.log(1024)),
        units.length - 1
    );

    return (this / Math.pow(1024, power)).toFixed(precision) + units[power];
}

console.log('10240 = ' + (10240).prefix()) // 10.00K
console.log('1234000 = ' + (1234000).prefix(1)) // 1.2M
console.log('10000 = ' + (-10000).prefix()) // -9.77K

Steely Wing
quelle
(11000) .prefix () entspricht 10.74K nicht sehr genau sollte 11.00K
bmaggi
1
@bmaggi Ändern Sie einfach die 1024 zu 1000
Steely Wing
1

Verbessern Sie die Antwort von @ tfmontague weiter, um Dezimalstellen zu formatieren. 33,0k bis 33k

largeNumberFormatter(value: number): any {
   let result: any = value;

   if (value >= 1e3 && value < 1e6) { result = (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K'; }
   if (value >= 1e6 && value < 1e9) { result = (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'; }
   if (value >= 1e9) { result = (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'T'; }

   return result;
}
Abdul Rahman
quelle
1

Keine der veröffentlichten Lösungen zufrieden, daher hier meine Version:

  1. Unterstützt positive und negative Zahlen
  2. Unterstützt negative Exponenten
  3. Rundet wenn möglich auf den nächsten Exponenten
  4. Führt eine Überprüfung der Grenzen durch (Fehler bei sehr großen / kleinen Zahlen nicht)
  5. Entfernt nachfolgende Nullen / Leerzeichen
  6. Unterstützt einen Präzisionsparameter

    function abbreviateNumber(number,digits=2) {
      var expK = Math.floor(Math.log10(Math.abs(number)) / 3);
      var scaled = number / Math.pow(1000, expK);
    
      if(Math.abs(scaled.toFixed(digits))>=1000) { // Check for rounding to next exponent
        scaled /= 1000;
        expK += 1;
      }
    
      var SI_SYMBOLS = "apμm kMGTPE";
      var BASE0_OFFSET = SI_SYMBOLS.indexOf(' ');
    
      if (expK + BASE0_OFFSET>=SI_SYMBOLS.length) { // Bound check
        expK = SI_SYMBOLS.length-1 - BASE0_OFFSET;
        scaled = number / Math.pow(1000, expK);
      }
      else if (expK + BASE0_OFFSET < 0) return 0;  // Too small
    
      return scaled.toFixed(digits).replace(/(\.|(\..*?))0+$/,'$2') + SI_SYMBOLS[expK+BASE0_OFFSET].trim();
    }
    
    //////////////////
    
    const tests = [
      [0.0000000000001,2],
      [0.00000000001,2],
      [0.000000001,2],
      [0.000001,2],
      [0.001,2],
      [0.0016,2],
      [-0.0016,2],
      [0.01,2],
      [1,2],
      [999.99,2],
      [999.99,1],
      [-999.99,1],
      [999999,2],
      [999999999999,2],
      [999999999999999999,2],
      [99999999999999999999,2],
    ];
    
    for (var i = 0; i < tests.length; i++) {
      console.log(abbreviateNumber(tests[i][0], tests[i][1]) );
    }

ttk
quelle
1

Ich habe mir einen sehr Code-Golf ausgedacht, und er ist sehr kurz!

var beautify=n=>((Math.log10(n)/3|0)==0)?n:Number((n/Math.pow(10,(Math.log10(n)/3|0)*3)).toFixed(1))+["","K","M","B","T",][Math.log10(n)/3|0];

console.log(beautify(1000))
console.log(beautify(10000000))

Craftingexpert1
quelle
1

Weitere Verbesserung von Salmans Antwort aufgrund von Fällen wie nFormatter (999999,1), die 1000K zurückgeben.

function formatNumberWithMetricPrefix(num, digits = 1) {
  const si = [
    {value: 1e18, symbol: 'E'},
    {value: 1e15, symbol: 'P'},
    {value: 1e12, symbol: 'T'},
    {value: 1e9, symbol: 'G'},
    {value: 1e6, symbol: 'M'},
    {value: 1e3, symbol: 'k'},
    {value: 0, symbol: ''},
  ];
  const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  function divideNum(divider) {
    return (num / (divider || 1)).toFixed(digits);
  }

  let i = si.findIndex(({value}) => num >= value);
  if (+divideNum(si[i].value) >= 1e3 && si[i - 1]) {
    i -= 1;
  }
  const {value, symbol} = si[i];
  return divideNum(value).replace(rx, '$1') + symbol;
}
Podvalnyi Mikhail
quelle
1

Der einfachste und einfachste Weg, dies zu tun, ist

new Intl.NumberFormat('en-IN', { 
    notation: "compact",
    compactDisplay: "short",
    style: 'currency',
    currency: 'INR'
}).format(1000).replace("T", "K")

Dies funktioniert für eine beliebige Anzahl. Einschließlich L Cretc.

Narasimha Reddy - Geeker
quelle
1

Durch Eliminieren der Schleife in der @ martin-sznapka-Lösung reduzieren Sie die Ausführungszeit um 40%.

function formatNum(num,digits) {
    let units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
    let floor = Math.floor(Math.abs(num).toString().length / 3);
    let value=+(num / Math.pow(1000, floor))
    return value.toFixed(value > 1?digits:2) + units[floor - 1];

}

Geschwindigkeitstest (200000 Zufallsstichproben) für eine andere Lösung als dieser Thread

Execution time: formatNum          418  ms
Execution time: kFormatter         438  ms it just use "k" no "M".."T" 
Execution time: beautify           593  ms doesnt support - negatives
Execution time: shortenLargeNumber 682  ms    
Execution time: Intl.NumberFormat  13197ms 
Feras
quelle
0
/*including negative values*/    
function nFormatter(num) {
      let neg = false;
       if(num < 0){
         num = num * -1;
         neg = true;
       }
       if (num >= 1000000000) {
         if(neg){
           return -1 * (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';  
         }
         return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
       }
       if (num >= 1000000) {
         if(neg){
           return -1 * (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';  
         }
         return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
       }
       if (num >= 1000) {
         if(neg){
           return -1 * (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';  
         }
         return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
       }
       return num;
    }
vivek kumawat
quelle
Bitte fügen Sie eine Erklärung Ihrer Lösung hinzu
Harun Diluka Heshan
0

Diese Funktion kann große Zahlen (sowohl positive als auch negative) in ein leserfreundliches Format umwandeln, ohne an Genauigkeit zu verlieren:

function abbrNum(n) {
    if (!n || (n && typeof n !== 'number')) {
      return '';
    }

    const ranges = [
      { divider: 1e12 , suffix: 't' },
      { divider: 1e9 , suffix: 'b' },
      { divider: 1e6 , suffix: 'm' },
      { divider: 1e3 , suffix: 'k' }
    ];
    const range = ranges.find(r => Math.abs(n) >= r.divider);
    if (range) {
      return (n / range.divider).toString() + range.suffix;
    }
    return n.toString();
}

/* test cases */
let testAry = [99, 1200, -150000, 9000000];
let resultAry = testAry.map(abbrNum);
console.log("result array: " + resultAry);

Hamzeen Hameem
quelle
0

Ich benutze diese Funktion. Es funktioniert für beide phpund javascript.

    /**
     * @param $n
     * @return string
     * Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc
     */
 function num_format($n) {
        $n_format = null;
        $suffix = null;
        if ($n > 0 && $n < 1000) {
           $n_format = Math.floor($n);   
            $suffix = '';
        }
        else if ($n == 1000) {
            $n_format = Math.floor($n / 1000);   //For PHP only use floor function insted of Math.floor()
            $suffix = 'K';
        }
        else if ($n > 1000 && $n < 1000000) {
            $n_format = Math.floor($n / 1000);
            $suffix = 'K+';
        } else if ($n == 1000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M';
        } else if ($n > 1000000 && $n < 1000000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M+';
        } else if ($n == 1000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B';
        } else if ($n > 1000000000 && $n < 1000000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B+';
        } else if ($n == 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T';
        } else if ($n >= 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T+';
        }


       /***** For PHP  ******/
       //  return !empty($n_format . $suffix) ? $n_format . $suffix : 0;

       /***** For Javascript ******/
        return ($n_format + $suffix).length > 0 ? $n_format + $suffix : 0;
    }
Schah
quelle
0

Ich habe mich entschlossen, die Antwort von @ Novellizator hier stark zu erweitern, um meinen Anforderungen gerecht zu werden. Ich wollte eine flexible Funktion, um die meisten meiner Formatierungsanforderungen ohne externe Bibliotheken zu erfüllen.

Eigenschaften

  • Option zur Verwendung von Auftragssuffixen (k, M usw.)
    • Option zum Angeben einer benutzerdefinierten Liste der zu verwendenden Auftragssuffixe
    • Option zum Einschränken der Min- und Max-Reihenfolge
  • Kontrolle über die Anzahl der Dezimalstellen
  • Automatische Kommas zur Trennung der Reihenfolge
  • Optionale Prozent- oder Dollarformatierung
  • Steuern Sie, was bei nicht numerischen Eingaben zurückgegeben werden soll
  • Funktioniert mit negativen und unendlichen Zahlen

Beispiele

let x = 1234567.8;
formatNumber(x);  // '1,234,568'
formatNumber(x, {useOrderSuffix: true});  // '1M'
formatNumber(x, {useOrderSuffix: true, decimals: 3, maxOrder: 1});  // '1,234.568k'
formatNumber(x, {decimals: 2, style: '$'});  // '$1,234,567.80'

x = 10.615;
formatNumber(x, {style: '%'});  // '1,062%'
formatNumber(x, {useOrderSuffix: true, decimals: 1, style: '%'});  // '1.1k%'
formatNumber(x, {useOrderSuffix: true, decimals: 5, style: '%', minOrder: 2});  // '0.00106M%'

formatNumber(-Infinity);  // '-∞'
formatNumber(NaN);  // ''
formatNumber(NaN, {valueIfNaN: NaN});  // NaN

Funktion

/*
 * Return the given number as a formatted string.  The default format is a plain
 * integer with thousands-separator commas.  The optional parameters facilitate
 * other formats:
 *   - decimals = the number of decimals places to round to and show
 *   - valueIfNaN = the value to show for non-numeric input
 *   - style
 *     - '%': multiplies by 100 and appends a percent symbol
 *     - '$': prepends a dollar sign
 *   - useOrderSuffix = whether to use suffixes like k for 1,000, etc.
 *   - orderSuffixes = the list of suffixes to use
 *   - minOrder and maxOrder allow the order to be constrained.  Examples:
 *     - minOrder = 1 means the k suffix should be used for numbers < 1,000
 *     - maxOrder = 1 means the k suffix should be used for numbers >= 1,000,000
 */
function formatNumber(number, {
    decimals = 0,
    valueIfNaN = '',
    style = '',
    useOrderSuffix = false,
    orderSuffixes = ['', 'k', 'M', 'B', 'T'],
    minOrder = 0,
    maxOrder = Infinity
  } = {}) {

  let x = parseFloat(number);

  if (isNaN(x))
    return valueIfNaN;

  if (style === '%')
    x *= 100.0;

  let order;
  if (!isFinite(x) || !useOrderSuffix)
    order = 0;
  else if (minOrder === maxOrder)
    order = minOrder;
  else {
    const unboundedOrder = Math.floor(Math.log10(Math.abs(x)) / 3);
    order = Math.max(
      0,
      minOrder,
      Math.min(unboundedOrder, maxOrder, orderSuffixes.length - 1)
    );
  }

  const orderSuffix = orderSuffixes[order];
  if (order !== 0)
    x /= Math.pow(10, order * 3);

  return (style === '$' ? '$' : '') +
    x.toLocaleString(
      'en-US',
      {
        style: 'decimal',
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals
      }
    ) +
    orderSuffix +
    (style === '%' ? '%' : '');
}
MarredCheese
quelle
0

Wow, hier gibt es so viele Antworten. Ich dachte, ich würde Ihnen geben, wie ich es gelöst habe, da es am einfachsten zu lesen schien, mit negativen Zahlen umgeht und weit im Kilo-Zahlenbereich für JavaScript liegt. Es wäre auch einfach, zu ändern, was Sie wollen oder noch weiter zu erweitern.

const symbols = [
  { 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' }
];

function numberFormatter(num, digits) {
  const numToCheck = Math.abs(num);
  for (let i = symbols.length - 1; i >= 0; i--) {
    if (numToCheck >= symbols[i].value) {
      const newNumber = (num / symbols[i].value).toFixed(digits);
      return `${newNumber}${symbols[i].symbol}`;
    }
  }
  return '0';
}

const 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 }
];
for (let i = 0; i < tests.length; i++) {
  console.log(`numberFormatter(${tests[i].num}, ${tests[i].digits})=${numberFormatter(tests[i].num, tests[i].digits)}`);
}

JT Turner
quelle