Định dạng một số là 2,5K nếu một nghìn trở lên, nếu không 900


152

Tôi cần hiển thị giá trị tiền tệ ở định dạng 1K bằng một nghìn hoặc 1.1K, 1.2K, 1.9K, v.v., nếu nó không phải là hàng nghìn, nếu không, dưới một nghìn, hiển thị 500, 100, 250 bình thường, v.v. , sử dụng javascript để định dạng số?


2
Bạn cũng cần MG?
Salman A

Tôi sẽ cần M có ... Bạn có thể giúp gì không?
Carl Weis

Câu trả lời:


209

Âm thanh như thế này sẽ làm việc cho bạn:

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


2
Đề xuất sửa chữa nhỏ ... Nên viết thường chữ k cho hàng ngàn. Thượng là cho Kilos. Đã thử chỉnh sửa, nhưng yêu cầu ít nhất 6 ký tự thay đổi trước khi thực hiện.
Adam Youngers

Làm thế nào để tôi chèn một biến php bên trong đây và sử dụng nó? tức là nếu biến số của tôi là $mynumber_outputnơi tôi chèn nó để sử dụng nó? Ví dụ: giả sử $mynumber_output= 12846, tôi muốn 12846 được chuyển đổi thành12.8k

Lưu ý rằng một kilobyte là 1024 byte trong một số trường hợp: en.wikipedia.org/wiki/Kilobyte
Olle Härstedt

Bất cứ ý tưởng làm thế nào chúng ta có thể làm cho 1000 hiển thị là 1,0k thay vì 1k?
Brent

1
Không hoàn toàn trả lời câu hỏi của người dùng. "Tôi sẽ cần M có ... Bạn có thể giúp gì không?" - Carl Weis
tfmontague

216

Một phiên bản tổng quát hơn:

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


@SalmanA - Trợ giúp tuyệt vời, sẽ thất bại nếu một người vượt qua dưới dạng chuỗi, nếu được làm sạch bằng parseFloat hoạt động tốt. Cảm ơn bạn!
Adesh M

1
Sửa nhỏ cho các số nhỏ hơn <1000, thêm {value: 1E0, ký hiệu: ""} vào var si =
Dimmduh

1
@GiovanniAzua chỉ cần thay thế if (num >= si[i].value)bằngif (Math.abs(num) >= si[i].value)
Salman A

những gì .replace(rx, "$1")làm gì?
M.Octavio

1
@ M.Octavio regex được sử dụng để cắt các số 0 ở cuối, ví dụ: 1.0trở thành 11.10trở thành1.1
Salman A

78

Đây là một giải pháp đơn giản giúp tránh tất cả các iftuyên bố (với sức mạnh của 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;
}

Phần thưởng Meme

Không đại diện SIcho cái gì?


Tôi thực sự thích giải pháp của bạn. Để có thể rút ngắn các giá trị âm, tôi nhân số đó với -1 trước và sau khi xác định cấp, vì Math.log10 (negValue) sẽ trả về NaN.
xhadon

Chỉ cần sử dụng Math.absđể thêm hỗ trợ cho các số âm, như thế : var tier = Math.log10(Math.abs(number)) / 3 | 0;.
Caio Tarifa

70

Cải thiện hơn nữa Câu trả lời của Salman vì nó trả về nFormatter (33000) là 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;
}

bây giờ nFormatter (33000) = 33K


2
Dù sao để làm điều này mà không làm tròn số? 1.590.000 sẽ trả lại 1.6M.
Brett Hardin

3
Đôi khi thật khó để biết khi nào nên đăng một câu trả lời mới về chỉnh sửa một câu hỏi hiện có, một điều tôi sử dụng để quyết định là nếu tôi ăn cắp mã từ câu trả lời của người dùng khác, tôi thường chỉnh sửa câu trả lời của họ để họ có thể nhận ra thay vì tôi ăn cắp mã.
MH

@Yash bạn là mã tôi đang cố thực hiện trong tập lệnh truy cập nhưng không nhận được đây là liên kết mã của tôi codepen.io/Merajkhan/pen/MMoxGE?editors=1010 Bạn có thể giúp tôi cách triển khai logic này không Các đơn vị K, L, M phải đến.
Mehraj Khan

Tuyệt quá. Giải pháp ngắn và ngọt ngào.
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 cho ý kiến, tôi đã loại bỏ sự phụ thuộc Math.round10.


1
Bạn có thể thay đổi nếu Math.abs(num) >= decimal.
Conor Pender

18

Rất nhiều câu trả lời trên luồng này khá phức tạp, sử dụng các đối tượng Math, đối tượng ánh xạ, vòng lặp for, regex, v.v. Nhưng những cách tiếp cận này không thực sự cải thiện khả năng đọc mã hoặc hiệu năng. Một cách tiếp cận thẳng về phía trước dường như cung cấp thiết kế tốt nhất.

Định dạng giá trị tiền mặt với K

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

console.log(formatCash(2500));

Định dạng giá trị tiền mặt với 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));

Sử dụng số âm

let format;
const number = -1235000;

if (number < 0) {
  format = '-' + formatCash(-1 * number);
} else {
  format = formatCash(number);
}

1
@Jan - Cập nhật bài viết của tôi với một ví dụ, nhưng cảm thấy nó đủ đơn giản để tính toán hình thức phủ định bằng cách sử dụng'-' + formatCash(-1 * number)
tfmontague

15

Cung cấp tín dụng cho Waylon Flinn nếu bạn thích điều này

Điều này đã được cải thiện từ cách tiếp cận thanh lịch hơn của anh ấy để xử lý các số âm và trường hợp ".0".

Càng ít vòng lặp và trường hợp "nếu" bạn có, IMO càng tốt.

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 với các trường hợp thử nghiệm -> https://jsfiddle.net/xyug4nvz/7/


1
Vẫn còn một lỗi khó chịu: abbreviateNumber(999999) == '1000k'thay vì '1M'. Điều này là do toFixed()cũng làm tròn số. Không chắc chắn cách khắc phục, mặc dù: /
Vitor Baptista

@VitorBaptista Nếu làm toFixed()tròn số dù thế nào đi nữa, bạn cũng có thể làm tròn số trước khi gửi tới abbreviateNumber(), để nó trả về 1Mthay vì 1000k. Không phải là một giải pháp, mà là một cách giải quyết.
forsureitsme

2
Nếu bạn không muốn làm tròn, bạn có thể thực hiện việc này sau bước chia tỷ lệ:const floored = Math.floor(scaled * 10) / 10;
tybro0103

14

ES2020 bổ sung hỗ trợ cho việc này trong Intl.NumberFormatSử dụng ký hiệu như sau:

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

NumberFormat thông số kỹ thuật:

Lưu ý rằng hiện tại không phải tất cả các trình duyệt đều hỗ trợ ES2020, vì vậy bạn có thể cần Polyfill này: https://formatjs.io/docs/polyfills/intl-numberformat


Gói đó đã không được chấp nhận, vì vậy vui lòng sử dụng liên kết này: npmjs.com/package/@formatjs/intl-numberformat
Ammad Khalid

2
Lưu ý: Chrome hỗ trợ notationcompactDisplaynhưng FireFox 77 và Safari 13.1 vẫn không hỗ trợ vì vậy bạn có thể sẽ cần polyfill.
Josh Unger

Wow, Firefox chỉ thêm hỗ trợ cho điều này trong câu 78, có vẻ như vậy. Tất nhiên, hơn 2 năm nữa, nhận xét này sẽ trông thật ngu ngốc. : P (Mặc dù thật buồn cười với tôi vì mã chạy cho tôi nhưng nó không chuyển đổi chính xác, vì vậy tôi sẽ cần phải cập nhật.)
Andrew

11

Điều này là khá thanh lịch.

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"


3

Cải thiện hơn nữa câu trả lời của @ Yash với hỗ trợ số âm:

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"

3

Bài đăng này khá cũ nhưng bằng cách nào đó tôi đã đạt đến bài đăng này để tìm kiếm một cái gì đó. SO để thêm đầu vào của tôi Số js là giải pháp một cửa bây giờ một ngày. Nó cung cấp một số lượng lớn các phương thức để giúp định dạng các số

http://numeraljs.com/


1
numeraljs không được duy trì nữa. Các ngã ba hoạt động mạnh nhất dường như là tê liệt . Nhưng cả hai đều không hỗ trợ ký hiệu SI / số liệu
Vincent de Lagabbe

2

Phương pháp ngắn và chung chung

Bạn có thể làm cho COUNT_FORMATSđối tượng cấu hình dài hoặc ngắn như bạn muốn., Tùy thuộc vào phạm vi giá trị bạn kiểm tra.

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


1

Thêm vào câu trả lời hàng đầu, điều này sẽ cung cấp 1k cho 1000 thay vì 1.0k

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

1

Một phiên bản sửa đổi của câu trả lời của Waylon Flinn với sự hỗ trợ cho số mũ âm:

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

Sản lượng dự kiến:

   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 }

1
  • Hỗ trợ số âm
  • Đang kiểm tra để mà !Number.isFinite
  • Thay đổi ' K M G T P E Z Y'thành ' K M'nếu bạn muốn đơn vị tối đa làM

Mã bên dưới là 1K = 1024, nếu bạn muốn 1K = 1000, hãy thay đổi tất cả 1024 thành 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


(11000) .prefix () bằng 10,74K không chính xác lắm nên nói 11.00K
bmaggi

1
@bmaggi Chỉ cần thay đổi 1024 thành 1000
Cánh hoàn toàn

1

Cải thiện câu trả lời của @ tfmontague để định dạng các vị trí thập phân. 33,0k đến 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;
}

1

Không hài lòng với bất kỳ giải pháp được đăng nào, vì vậy đây là phiên bản của tôi:

  1. Hỗ trợ số dương và số âm
  2. Hỗ trợ số mũ âm
  3. Làm tròn đến số mũ tiếp theo nếu có thể
  4. Thực hiện kiểm tra giới hạn (không lỗi với số lượng rất lớn / nhỏ)
  5. Loại bỏ các số 0 / dấu cách
  6. Hỗ trợ một tham số chính xác

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


1

Tôi đã đưa ra một mã golf rất mã, và nó rất ngắn!

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


1

Cải thiện hơn nữa Câu trả lời của Salman vì các trường hợp như nFormatter (999999,1) trả lại 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;
}

1

Cách đơn giản nhất và dễ nhất để làm điều này là

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

Điều này làm việc cho bất kỳ số. Bao gồm cả L Crvv


1

Bằng cách loại bỏ vòng lặp trong giải pháp @ martin-sznapka, bạn sẽ giảm 40% thời gian thực hiện.

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

}

Kiểm tra tốc độ (200000 mẫu ngẫu nhiên) cho giải pháp khác nhau từ chuỗi này

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 

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

vui lòng thêm một số giải thích về giải pháp của bạn
Harun Diluka Heshan 15/03/18

0

Hàm này có thể chuyển đổi số lượng lớn (cả tích cực & tiêu cực) thành định dạng thân thiện với người đọc mà không làm mất độ chính xác của nó:

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


0

Tôi đang sử dụng chức năng này. Nó hoạt động cho cả phpjavascript.

    /**
     * @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;
    }

0

Tôi quyết định mở rộng rất nhiều câu trả lời của @ Novellizator tại đây để đáp ứng nhu cầu của tôi. Tôi muốn một chức năng linh hoạt để xử lý hầu hết các nhu cầu định dạng của mình mà không cần các thư viện bên ngoài.

Đặc trưng

  • Tùy chọn sử dụng hậu tố thứ tự (k, M, v.v.)
    • Tùy chọn để chỉ định một danh sách tùy chỉnh các hậu tố đơn hàng sẽ sử dụng
    • Tùy chọn để giới hạn thứ tự tối thiểu và tối đa
  • Kiểm soát số lượng vị trí thập phân
  • Dấu phẩy phân tách tự động
  • Định dạng phần trăm hoặc đô la tùy chọn
  • Kiểm soát những gì sẽ trả về trong trường hợp đầu vào không phải là số
  • Hoạt động trên số âm và vô hạn

Ví dụ

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

Chức năng

/*
 * 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 === '%' ? '%' : '');
}

0

Wow có rất nhiều câu trả lời ở đây. Tôi nghĩ rằng tôi sẽ cung cấp cho bạn cách tôi giải quyết nó vì nó có vẻ dễ đọc nhất, xử lý các số âm và đi xa trong phạm vi số kilo cho JavaScript. Nó cũng sẽ dễ dàng thay đổi thành những gì bạn muốn hoặc mở rộng hơn nữa.

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


0

Một thay thế ngắn hơn:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.