我需要显示一个货币值的格式1K等于一千,或1.1K, 1.2K, 1.9K等,如果它不是一个偶数千,否则如果低于一千,显示正常500,100,250等,使用JavaScript格式化的数字?
当前回答
韦伦·弗林解决方案的2020版。
const SI_SYMBOLS = ["", "k", "M", "G", "T", "P", "E"];
const abbreviateNumber = (number, minDigits, maxDigits) => {
if (number === 0) return number;
// determines SI symbol
const tier = Math.floor(Math.log10(Math.abs(number)) / 3);
// get suffix and determine scale
const suffix = SI_SYMBOLS[tier];
const scale = 10 ** (tier * 3);
// scale the number
const scaled = number / scale;
// format number and add suffix
return scaled.toLocaleString(undefined, {
minimumFractionDigits: minDigits,
maximumFractionDigits: maxDigits,
}) + suffix;
};
Tests and examples: const abbreviateNumberFactory = (symbols) => ( (number, minDigits, maxDigits) => { if (number === 0) return number; // determines SI symbol const tier = Math.floor(Math.log10(Math.abs(number)) / 3); // get suffix and determine scale const suffix = symbols[tier]; const scale = 10 ** (tier * 3); // scale the number const scaled = number / scale; // format number and add suffix return scaled.toLocaleString(undefined, { minimumFractionDigits: minDigits, maximumFractionDigits: maxDigits, }) + suffix; } ); const SI_SYMBOLS = ["", "k", "M", "G", "T", "P", "E"]; const SHORT_SYMBOLS = ["", "K", "M", "B", "T", "Q"]; const LONG_SYMBOLS = ["", " thousand", " million", " billion", " trillion", " quadrillion"]; const abbreviateNumberSI = abbreviateNumberFactory(SI_SYMBOLS); const abbreviateNumberShort = abbreviateNumberFactory(SHORT_SYMBOLS); const abbreviateNumberLong = abbreviateNumberFactory(LONG_SYMBOLS); const tests = [1e5, -9e7, [1009999.999, 2], [245345235.34513, 1, 1], [-72773144123, 3] ]; const functions = { abbreviateNumberSI, abbreviateNumberShort, abbreviateNumberLong, }; tests.forEach((test) => { const testValue = Array.isArray(test) ? test : [test]; Object.entries(functions).forEach(([key, func]) => { console.log(`${key}(${testValue.join(', ')}) = ${func(...testValue)}`); }); });
其他回答
通过消除@martin-sznapka解决方案中的循环,您将减少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];
}
速度测试(200000随机样本)从这个线程不同的解决方案
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
这个函数可以将巨大的数字(正数和负数)转换为读者友好的格式,而不会失去其精度:
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”的情况。
循环和“如果”情况越少,IMO就越好。
function abbreviateNumber(number) {
const SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"];
const sign = number < 0 ? '-1' : '';
const absNumber = Math.abs(number);
const tier = Math.log10(absNumber) / 3 | 0;
// if zero, we don't need a prefix
if(tier == 0) return `${absNumber}`;
// get postfix and determine scale
const postfix = SI_POSTFIXES[tier];
const scale = Math.pow(10, tier * 3);
// scale the number
const scaled = absNumber / scale;
const floored = Math.floor(scaled * 10) / 10;
// format number and add postfix as suffix
let str = floored.toFixed(1);
// remove '.0' case
str = (/\.0$/.test(str)) ? str.substr(0, str.length - 2) : str;
return `${sign}${str}${postfix}`;
}
jsFiddle测试用例-> https://jsfiddle.net/qhbrz04o/9/
不满足任何张贴的解决方案,所以这是我的版本:
Supports positive and negative numbers Supports negative exponents Rounds up to next exponent if possible Performs bounds checking (doesn't error out for very large/small numbers) Strips off trailing zeros/spaces Supports a precision parameter 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]) ); }
这里有一个简单的解决方案,可以避免所有的if语句(借助Math的力量)。
var SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"];
function abbreviateNumber(number){
// what tier? (determines SI symbol)
var tier = Math.log10(Math.abs(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;
}
奖金模因
SI代表什么?
推荐文章
- 转换php数组到Javascript
- 如何跳转到浏览器页面的顶部
- 确定$。Ajax错误是一个超时
- 在电子邮件消息中是否支持JavaScript ?
- 如何在JavaScript中指定Math.log()的基?
- 多重左赋值JavaScript
- 使用jQuery创建、读取和删除cookie
- 如何在单个测试基础上更改模拟实现?
- VueJS有条件地为元素添加属性
- Uncaught TypeError:(中间值)(…)不是一个函数
- 如何设置URL查询参数在Vue与Vue路由器
- 无法读取属性“addEventListener”为空
- 如何防止moment.js从webpack加载地区?
- getMonth在javascript中给出前一个月
- 如何在禁用按钮上启用引导工具提示?