Sformatuj liczbę jako 2,5 KB, jeśli jest to tysiąc lub więcej, w przeciwnym razie 900

152

Muszę pokazać wartość waluty w formacie 1K równym tysiącowi lub 1,1K, 1,2K, 1,9K itd., Jeśli nie są to nawet tysiące, w przeciwnym razie, jeśli poniżej tysiąca, wyświetl normalne 500, 100, 250 itd. , używając javascript do sformatowania numeru?

Carl Weis
źródło
2
Czy potrzebujesz również Mi G?
Salman A
Będę potrzebował M tak ... Możesz pomóc?
Carl Weis,

Odpowiedzi:

209

Brzmi tak, że powinno działać dla Ciebie:

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
źródło
2
Sugerowana drobna poprawka ... Powinna być zapisana małymi literami k dla tysięcy. Górna jest dla kilogramów. Próbowano edytować, ale wymaga zmiany co najmniej 6 znaków, zanim to zajmie.
Adam Youngers
Jak wstawić tutaj zmienną php i użyć jej? tj. jeśli moja zmienna liczbowa jest $mynumber_outputgdzie mam ją wstawić, aby jej użyć? Na przykład, powiedzmy $mynumber_output= 12846, chciałbym przekonwertować 12.8k
Zwróć uwagę, że w niektórych przypadkach jeden kilobajt to 1024 bajty: en.wikipedia.org/wiki/Kilobyte
Olle Härstedt
Masz jakiś pomysł, jak możemy wyświetlić 1000 jako 1.0k zamiast 1k?
Brent
1
Nie odpowiada całkowicie na pytanie użytkownika. "Będę potrzebował M, tak ... Czy możesz pomóc?" - Carl Weis
tfmontague
216

Bardziej uogólniona wersja:

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
źródło
@SalmanA - Wielka pomoc, nie powiedzie się, jeśli jeden przekaże argument jako łańcuch, jeśli zostanie wyczyszczony za pomocą parseFloat, działa dobrze. Dziękuję Ci!
Adesh M
1
Mała poprawka dla liczb mniejszych <1000, dodaj {wartość: 1E0, symbol: ""} do var si =
Dimmduh
1
@GiovanniAzua prostu zastąpić if (num >= si[i].value)zif (Math.abs(num) >= si[i].value)
Salman A
Co ma .replace(rx, "$1")zrobić?
M.Octavio
1
@ M.Octavio wyrażenie regularne służy do przycinania końcowych zer, np. 1.0Staje się 1i 1.10staje się1.1
Salman A
78

Oto proste rozwiązanie, które pozwala uniknąć wszystkich ifinstrukcji (z mocą 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

Co to znaczy SI?

Waylon Flinn
źródło
Naprawdę podoba mi się twoje rozwiązanie. Aby móc skrócić również wartości ujemne, mnożę liczbę przez -1 przed i po określeniu warstwy, ponieważ Math.log10 (wartość ujemna) zwróci NaN.
xhadon,
Wystarczy użyć Math.abs, aby dodać wsparcie dla liczb ujemnych, tak: var tier = Math.log10(Math.abs(number)) / 3 | 0;.
Caio Tarifa
70

Dalsze ulepszanie odpowiedzi Salmana, ponieważ zwraca nFormatter (33000) jako 33,0K

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

teraz nFormatter (33000) = 33K

Yash
źródło
2
Zresztą zrobić to bez zaokrąglania liczby? 1590 000 zwróci 1,6 mln.
Brett Hardin
3
Czasami trudno jest wiedzieć, kiedy opublikować nową odpowiedź lub edytować istniejącą. Decyduję się na to, że kradnę kod od odpowiedzi innych użytkowników. kod.
MH
@Yash jesteś kodem, który próbuję zaimplementować w skrypcie licznika, ale nie otrzymuję tego linku do kodu kodepen.io/Merajkhan/pen/MMoxGE?editors=1010 Czy możesz mi pomóc, jak zaimplementować tę logikę, którą chcę Jednostki K, L, M muszą przyjść.
Mehraj Khan
Wspaniały. Krótkie i słodkie rozwiązanie.
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;
}

Dzięki @Cos za komentarz, usunąłem zależność Math.round10.

Martin Sznapka
źródło
1
Możesz zmienić if na Math.abs(num) >= decimal.
Conor Pender,
18

Wiele odpowiedzi w tym wątku staje się dość skomplikowanych, przy użyciu obiektów Math, obiektów map, pętli for, wyrażeń regularnych itp. Jednak te podejścia tak naprawdę nie poprawiają czytelności kodu ani wydajności. Wydaje się, że najlepszy projekt zapewnia proste podejście.

Formatowanie wartości Cash za pomocą K.

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

console.log(formatCash(2500));

Formatowanie wartości gotówkowej za pomocą KMBT

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

Korzystanie z liczb ujemnych

let format;
const number = -1235000;

if (number < 0) {
  format = '-' + formatCash(-1 * number);
} else {
  format = formatCash(number);
}
tfmontague
źródło
1
@Jan - Zaktualizowałem mój post przykładem, ale czułem, że obliczenie negatywnej formy za pomocą'-' + formatCash(-1 * number)
tfmontague
15

Jeśli ci się spodoba, przekaż Waylon Flinn

Zostało to ulepszone w porównaniu z bardziej eleganckim podejściem do obsługi liczb ujemnych i przypadku „.0”.

Im mniej masz pętli i przypadków „jeśli”, tym lepsza 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 z przypadkami testowymi -> https://jsfiddle.net/xyug4nvz/7/

Jason Sebring
źródło
1
Nadal jest irytujący błąd: abbreviateNumber(999999) == '1000k'zamiast '1M'. Dzieje się tak, ponieważ toFixed()również zaokrągla liczby. Nie wiem jednak, jak to naprawić: /
Vitor Baptista
@VitorBaptista Jeśli toFixed()mimo to zaokrągli liczbę, równie dobrze możesz zaokrąglić liczbę przed wysłaniem abbreviateNumber(), aby 1Mzamiast tego zwracała 1000k. Nie rozwiązanie, ale obejście.
forsureitsme
2
Jeśli nie chcesz zaokrąglania, możesz to zrobić po kroku skali:const floored = Math.floor(scaled * 10) / 10;
tybro0103
14

ES2020 dodaje obsługę tego przy Intl.NumberFormatużyciu notacji w następujący sposób:

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

NumberFormat okular:

Zauważ, że w tej chwili nie wszystkie przeglądarki obsługują ES2020, więc możesz potrzebować tego Polyfill: https://formatjs.io/docs/polyfills/intl-numberformat

Ori Price
źródło
Ten pakiet został wycofany, więc użyj tego linku: npmjs.com/package/@formatjs/intl-numberformat
Ammad Khalid
2
Uwaga: Chrome obsługuje notationi, compactDisplayale FireFox 77 i Safari 13.1 nadal go nie obsługują, więc prawdopodobnie będziesz potrzebować polyfill.
Josh Unger
Wow, wydaje się, że Firefox właśnie dodał obsługę tego w wersji 78. Oczywiście za 2 lata ten komentarz będzie wyglądał głupio. : P (To dla mnie zabawne, ponieważ kod działa za mnie, ale nie konwertuje poprawnie, więc muszę zrobić aktualizację.)
Andrew
11

to jest całkiem eleganckie.

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
źródło
4

Możesz użyć pakietu w formacie d3 wzorowanego na Python Advanced String Formatting PEP3101 :

var f = require('d3-format')
console.log(f.format('.2s')(2500)) // displays "2.5k"
Vincent de Lagabbe
źródło
3

Dalsza poprawa odpowiedzi @ Yash z obsługą liczb ujemnych:

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"
Truskawka
źródło
3

Ten post jest dość stary, ale jakoś do niego dotarłem szukając czegoś. SO, aby dodać moje dane wejściowe Numeral js to rozwiązanie jednego przystanku teraz dni. Zawiera wiele metod ułatwiających formatowanie liczb

http://numeraljs.com/

Vatsal
źródło
1
numeraljs nie jest już utrzymywany. Najbardziej aktywny widelec wydaje się być odrętwiały . Ale żaden z nich nie obsługuje notacji SI / metrycznej
Vincent de Lagabbe
2

Metoda krótka i ogólna

Możesz COUNT_FORMATSustawić obiekt konfiguracyjny tak długi lub krótki, jak chcesz., W zależności od testowanego zakresu wartości.

// 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
źródło
1

Dodając górną odpowiedź, da to 1k za 1000 zamiast 1,0k

function kFormatter(num) {
    return num > 999 ? num % 1000 === 0 ? (num/1000).toFixed(0) + 'k' : (num/1000).toFixed(1) + 'k' : num
}
rajatbarman
źródło
1

Zmodyfikowana wersja odpowiedzi Waylona Flinna z obsługą ujemnych wykładników:

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

Oczekiwany wynik:

   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
źródło
1
  • Obsługa liczby ujemnej
  • Sprawdzanie dla !Number.isFinite
  • Zmień ' K M G T P E Z Y'na, ' K M'jeśli chcesz, aby maksymalna jednostka toM

Poniższy kod to 1K = 1024, jeśli chcesz 1K = 1000, zmień wszystkie 1024 na 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
źródło
(11000) .prefix () równa się 10,74K niezbyt dokładne powinno oznaczać 11,00K
bmaggi
1
@bmaggi Po prostu zmień 1024 na 1000
Steely Wing
1

Dalsze ulepszanie odpowiedzi @ tfmontague w celu formatowania miejsc dziesiętnych. 33,0 tys. Do 33 tys

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
źródło
1

Nie spełnia żadnego z opublikowanych rozwiązań, więc oto moja wersja:

  1. Obsługuje liczby dodatnie i ujemne
  2. Obsługuje ujemne wykładniki
  3. Jeśli to możliwe, zaokrągla w górę do następnego wykładnika
  4. Sprawdza granice (nie wyświetla błędów przy bardzo dużych / małych liczbach)
  5. Usuwa końcowe zera / spacje
  6. Obsługuje parametr precyzji

    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
źródło
1

Wymyśliłem bardzo kodowaną grę w golfa i jest bardzo krótka!

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
źródło
1

Dalsze ulepszanie odpowiedzi Salmana z powodu przypadków takich jak nFormatter (999999,1), który zwraca 1000K.

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
źródło
1

Najprostszym i najłatwiejszym sposobem na to jest

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

Działa to dla dowolnej liczby. W tym L Critp.

Narasimha Reddy - Geeker
źródło
1

Eliminując pętlę w rozwiązaniu @ martin-sznapka, zredukujesz czas wykonania o 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];

}

Test szybkości (200000 losowych próbek) dla innego rozwiązania z tego wątku

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
źródło
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
źródło
proszę dodać wyjaśnienie swojego rozwiązania
Harun Diluka Heshan
0

Ta funkcja może przekształcić ogromne liczby (zarówno dodatnie, jak i ujemne) w format przyjazny dla czytelnika bez utraty precyzji:

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
źródło
0

Używam tej funkcji. Działa zarówno w przypadku, jak phpi 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;
    }
szach w persji
źródło
0

Postanowiłem znacznie rozszerzyć odpowiedź @ Novellizator tutaj, aby zaspokoić moje potrzeby. Chciałem elastycznej funkcji, która poradziłaby sobie z większością moich potrzeb związanych z formatowaniem bez zewnętrznych bibliotek.

cechy

  • Możliwość używania przyrostków kolejności (k, M itp.)
    • Możliwość określenia niestandardowej listy sufiksów zamówień do użycia
    • Możliwość ograniczenia minimalnego i maksymalnego zamówienia
  • Kontrola liczby miejsc dziesiętnych
  • Automatyczne przecinki oddzielające zamówienia
  • Opcjonalne formatowanie procentowe lub dolarowe
  • Kontrola nad tym, co ma zostać zwrócone w przypadku wprowadzania nieliczbowego
  • Działa na liczbach ujemnych i nieskończonych

Przykłady

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

Funkcjonować

/*
 * 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
źródło
0

Wow, jest tu tak wiele odpowiedzi. Pomyślałem, że podam ci, jak go rozwiązałem, ponieważ wydawało się, że jest najłatwiejszy do odczytania, obsługuje liczby ujemne i wykracza daleko w zakresie kilogramów dla JavaScript. Łatwo byłoby również zmienić to, co chcesz lub rozszerzyć jeszcze bardziej.

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
źródło
0

Krótsza alternatywa:

function nFormatter(num) {
    const format = [
      { 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: 1, symbol: '' },
    ];
    const formatIndex = format.findIndex((data) => num >= data.value);
    console.log(formatIndex)
    return (num / format[formatIndex === -1? 6: formatIndex].value).toFixed(2) + format[formatIndex === -1?6: formatIndex].symbol;
  }
  

wkwkwk
źródło