我需要显示一个货币值的格式1K等于一千,或1.1K, 1.2K, 1.9K等,如果它不是一个偶数千,否则如果低于一千,显示正常500,100,250等,使用JavaScript格式化的数字?
当前回答
进一步改进Salman's Answer,因为像nFormatter(9999999,1)这样的情况返回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;
}
其他回答
这个函数可以将巨大的数字(正数和负数)转换为读者友好的格式,而不会失去其精度:
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);
哇,这里有这么多答案。我想我会告诉你我是如何解决它的,因为它似乎是最容易阅读的,处理负数,并且在JavaScript的千位数范围内。它也很容易改变到你想要的或进一步扩展。
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)}`); }
/*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;
}
我决定在这里扩展@Novellizator的答案,以满足我的需求。我想要一个灵活的函数来处理我的大部分格式化需求,而不需要外部库。
特性
选择使用顺序后缀(k, M等) 选项指定要使用的订单后缀的自定义列表 选项来约束最小和最大顺序 控制小数点后的位数 自动顺序分隔逗号 可选百分比或美元格式 控制在非数字输入的情况下返回什么 适用于负数和无穷数
例子
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
函数
/*
* 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 === '%' ? '%' : '');
}
function transform(value,args) {
const suffixes = ['K', 'M', 'B', 'T', 'P', 'E'];
if (!value) {
return null;
}
if (Number.isNaN(value)) {
return null;
}
if (value < 1000) {
return value;
}
const exp = Math.floor(Math.log(value) / Math.log(1000));
const returnValue = (value / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1];
return returnValue;
}
变换(9999 2)
/ /“10.00 k”