Format angka sebagai 2.5K jika seribu atau lebih, jika tidak 900

152

Saya perlu menunjukkan nilai mata uang dalam format 1K yang sama dengan seribu, atau 1.1K, 1.2K, 1.9K dll, jika bukan ribuan bahkan, jika di bawah seribu, menampilkan normal 500, 100, 250 dll , menggunakan javascript untuk memformat angka?

Carl Weis
sumber
2
Apakah Anda juga butuh Mdan G?
Salman A
Saya akan membutuhkan M ya ... Bisakah Anda membantu?
Carl Weis

Jawaban:

209

Kedengarannya seperti ini cocok untuk Anda:

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
sumber
2
Perbaikan kecil disarankan ... Seharusnya k huruf kecil untuk ribuan. Atas adalah untuk Kilo. Sudah mencoba mengedit, tetapi membutuhkan setidaknya 6 karakter yang diubah sebelum akan diambil.
Adam Youngers
Bagaimana cara memasukkan variabel php di dalam sini dan menggunakannya? yaitu jika variabel nomor saya adalah di $mynumber_outputmana saya memasukkan ini untuk menggunakannya? Misalnya, katakan $mynumber_output= 12846, saya ingin 12846 dikonversi menjadi12.8k
Perhatikan bahwa satu kilobyte adalah 1024 byte dalam beberapa kasus: en.wikipedia.org/wiki/Kilobyte
Olle Härstedt
Adakah yang tahu bagaimana kita dapat membuat 1000 tampilan sebagai 1.0k bukan 1k?
Brent
1
Tidak sepenuhnya menjawab pertanyaan pengguna. "Aku akan membutuhkan M ya ... Bisakah kamu membantu?" - Carl Weis
tfmontague
217

Versi yang lebih umum:

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
sumber
@SalmanA - Sangat membantu, gagal jika satu pass arg sebagai string, jika dibersihkan dengan parseFloat berfungsi dengan baik. Terima kasih!
Adesh M
1
Perbaikan kecil untuk angka kurang <1000, tambahkan {value: 1E0, simbol: ""} ke var si =
Dimmduh
1
@GiovanniAzua baru saja ganti if (num >= si[i].value)denganif (Math.abs(num) >= si[i].value)
Salman A
apa yang .replace(rx, "$1")harus dilakukan
M.Octavio
1
@ M.Octavio regex digunakan untuk memotong nol trailing misalnya 1.0menjadi 1dan 1.10menjadi1.1
Salman A
78

Inilah solusi sederhana yang menghindari semua ifpernyataan (dengan kekuatan 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

Apa artinya SI?

Waylon Flinn
sumber
Saya sangat suka solusi Anda. Untuk dapat mempersingkat nilai negatif juga, saya mengalikan angka dengan -1 sebelum dan setelah menentukan tingkat, karena Math.log10 (negativeValue) akan mengembalikan NaN.
xhadon
Cukup gunakan Math.absuntuk menambahkan dukungan untuk angka negatif, seperti itu: var tier = Math.log10(Math.abs(number)) / 3 | 0;.
Caio Tarifa
71

Lebih lanjut meningkatkan Jawaban Salman karena mengembalikan nFormatter (33000) sebagai 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;
}

sekarang nFormatter (33000) = 33K

Yash
sumber
2
Pokoknya melakukan ini tanpa membulatkan angka? 1,590,000 akan mengembalikan 1,6 juta.
Brett Hardin
3
Terkadang sulit untuk mengetahui kapan harus mengirim jawaban baru untuk mengedit yang sudah ada, sesuatu yang saya gunakan untuk memutuskan adalah jika saya mencuri kode dari pengguna lain menjawab, saya biasanya mengedit jawaban mereka sehingga mereka bisa mendapatkan pengakuan alih-alih saya mencuri mereka kode.
MH
@Yash kamu kode yang saya coba terapkan dalam script counter tetapi tidak mendapatkan ini adalah tautan codepen saya codepen.io/Merajkhan/pen/MMoxGE?editors=1010 Dapatkah Anda membantu saya bagaimana menerapkan logika ini yang saya inginkan Unit K, L, M harus datang.
Mehraj Khan
Bagus. Solusi singkat dan Manis.
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 untuk komentar, saya menghapus dependensi Math.round10.

Martin Sznapka
sumber
1
Anda dapat mengubah if to Math.abs(num) >= decimal.
Conor Pender
18

Banyak jawaban di utas ini menjadi agak rumit, menggunakan objek Matematika, objek peta, for-loop, regex, dll. Tetapi pendekatan ini tidak benar-benar meningkatkan keterbacaan kode, atau kinerja. Pendekatan lurus ke depan tampaknya menawarkan desain terbaik.

Memformat nilai tunai dengan K

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

console.log(formatCash(2500));

Memformat nilai tunai dengan 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));

Menggunakan angka negatif

let format;
const number = -1235000;

if (number < 0) {
  format = '-' + formatCash(-1 * number);
} else {
  format = formatCash(number);
}
Timbul
sumber
1
@ Jan - Diperbarui posting saya dengan contoh, tetapi merasa itu cukup sederhana untuk menghitung bentuk negatif menggunakan'-' + formatCash(-1 * number)
tfmontague
15

Berikan Kredit pada Waylon Flinn jika Anda suka ini

Ini ditingkatkan dari pendekatannya yang lebih elegan untuk menangani angka negatif dan kasus ".0".

Semakin sedikit loop dan kasus "jika" yang Anda miliki, semakin baik 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 dengan test case -> https://jsfiddle.net/xyug4nvz/7/

Jason Sebring
sumber
1
Masih ada bug yang mengganggu: abbreviateNumber(999999) == '1000k'bukannya '1M'. Ini karena toFixed()juga membulatkan angka. Tidak yakin bagaimana cara memperbaikinya, meskipun: /
Vitor Baptista
@VitorBaptista Jika toFixed()putaran nomor pula, Anda mungkin juga putaran nomor sebelum mengirimnya ke abbreviateNumber(), sehingga kembali 1Mbukan 1000k. Bukan solusi, tetapi solusi.
forsureitsme
2
Jika Anda tidak ingin pembulatan, Anda dapat melakukan ini setelah langkah skala:const floored = Math.floor(scaled * 10) / 10;
tybro0103
14

ES2020 menambahkan dukungan untuk ini dalam Intl.NumberFormatMenggunakan notasi sebagai berikut:

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

NumberFormat spesifikasi:

Perhatikan bahwa saat ini tidak semua browser mendukung ES2020, jadi Anda mungkin memerlukan Polyfill ini: https://formatjs.io/docs/polyfills/intl-numberformat

Harga Ori
sumber
Paket itu telah ditinggalkan, jadi silakan gunakan tautan ini: npmjs.com/package/@formatjs/intl-numberformat
Ammad Khalid
2
Catatan: Chrome mendukung notationdan compactDisplaytetapi FireFox 77 dan Safari 13.1 masih tidak mendukungnya sehingga Anda kemungkinan akan memerlukan polyfill.
Josh Unger
Wow, Firefox baru saja menambahkan dukungan untuk ini dalam v. 78, tampaknya. Tentu saja, 2+ tahun dari sekarang, komentar ini akan terlihat bodoh. : P (Ini lucu bagiku karena kodenya berjalan untukku tetapi tidak dikonversi dengan benar, jadi aku harus melakukan pembaruan.)
Andrew
11

ini cukup elegan.

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
sumber
4

Anda dapat menggunakan paket format-d3 yang dimodelkan setelah Python Advanced String Formatting PEP3101 :

var f = require('d3-format')
console.log(f.format('.2s')(2500)) // displays "2.5k"
Vincent de Lagabbe
sumber
3

Lebih meningkatkan jawaban @ Yash dengan dukungan angka negatif:

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"
Stroberi
sumber
3

Posting ini cukup lama tetapi saya entah bagaimana mencapai ke posting ini mencari sesuatu. SO untuk menambahkan input saya. Angka adalah solusi satu atap sekarang menjadi beberapa hari. Ini memberikan sejumlah besar metode untuk membantu memformat angka

http://numeraljs.com/

Vatsal
sumber
1
numeraljs tidak dipertahankan lagi. Garpu paling aktif tampaknya numbro . Tapi tak satu pun dari mereka yang mendukung notasi SI / metrik
Vincent de Lagabbe 3-15
2

Metode pendek dan generik

Anda bisa membuat COUNT_FORMATSobjek konfigurasi sepanjang atau sesingkat yang Anda inginkan., Tergantung pada rentang nilai yang Anda uji.

// 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
sumber
1

Menambahkan pada jawaban teratas, ini akan memberikan 1k untuk 1000, bukan 1.0k

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

Versi modifikasi dari jawaban Waylon Flinn dengan dukungan untuk eksponen negatif:

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

Output yang diharapkan:

   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
sumber
1
  • Mendukung angka negatif
  • Memeriksa !Number.isFinite
  • Ubah ' K M G T P E Z Y'ke ' K M'jika Anda ingin unit maksM

Kode di bawah ini adalah 1K = 1024, jika Anda ingin 1K = 1000, ubah semua 1024 menjadi 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
sumber
(11000) .prefix () sama dengan 10.74K tidak terlalu akurat seharusnya mengatakan 11.00K
bmaggi
1
@ bmaggi Ubah saja 1024 menjadi 1000
Steely Wing
1

Meningkatkan jawaban @ tfmontague lebih lanjut untuk memformat tempat desimal. 33,0k hingga 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
sumber
1

Tidak puas dengan salah satu solusi yang diposting, jadi inilah versi saya:

  1. Mendukung angka positif dan negatif
  2. Mendukung eksponen negatif
  3. Membulatkan ke eksponen berikutnya jika memungkinkan
  4. Melakukan pemeriksaan batas (tidak kesalahan untuk jumlah yang sangat besar / kecil)
  5. Strip off trailing nol / spasi
  6. Mendukung parameter presisi

    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
sumber
1

Saya datang dengan kode yang sangat golf, dan itu sangat singkat!

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
sumber
1

Lebih lanjut meningkatkan Jawaban Salman karena kasus-kasus seperti nFormatter (999999,1) yang mengembalikan 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
sumber
1

Cara termudah dan termudah untuk melakukan ini adalah

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

Ini berfungsi untuk nomor berapa pun. Termasuk L Crdll

Narasimha Reddy - Geeker
sumber
1

Dengan menghilangkan loop dalam solusi @ martin-sznapka, Anda akan mengurangi waktu eksekusi hingga 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];

}

Tes kecepatan (200000 sampel acak) untuk solusi berbeda dari utas ini

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
sumber
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
sumber
tolong tambahkan beberapa penjelasan tentang solusi Anda
Harun Diluka Heshan
0

Fungsi ini dapat mengubah angka besar (baik positif & negatif) menjadi format ramah pembaca tanpa kehilangan ketepatannya:

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
sumber
0

Saya menggunakan fungsi ini. Ini bekerja untuk keduanya phpdan 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;
    }
shah
sumber
0

Saya memutuskan untuk memperluas banyak jawaban @ Novellizator di sini untuk memenuhi kebutuhan saya. Saya ingin fungsi yang fleksibel untuk menangani sebagian besar kebutuhan format saya tanpa perpustakaan eksternal.

fitur

  • Opsi untuk menggunakan sufiks pesanan (k, M, dll.)
    • Opsi untuk menentukan daftar sufiks pesanan khusus untuk digunakan
    • Opsi untuk membatasi min dan max order
  • Kontrol atas jumlah tempat desimal
  • Tanda pemisah pesanan otomatis
  • Format persen atau dolar opsional
  • Kontrol atas apa yang harus dikembalikan jika input non-numerik
  • Bekerja pada angka negatif dan tak terbatas

Contohnya

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

Fungsi

/*
 * 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
sumber
0

Wow, ada begitu banyak jawaban di sini. Saya pikir saya akan memberi Anda bagaimana saya menyelesaikannya karena tampaknya yang paling mudah dibaca, menangani angka negatif, dan jauh melampaui kisaran angka kilo untuk JavaScript. Ini juga akan mudah untuk mengubah apa yang Anda inginkan atau bahkan lebih jauh.

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
sumber
0

Alternatif yang lebih pendek:

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
sumber