在JavaScript中将长数字转换为缩写字符串,并有一个特殊的简短要求

在JavaScript中将长数字转换为缩写字符串,并有一个特殊的简短要求,javascript,numbers,Javascript,Numbers,在JavaScript中,如何编写一个函数,将给定的[edit:正整数]数字(1000亿以下)转换为3个字母的缩写——其中0-9和a-z/a-z作为一个字母计算,但点(因为它在许多比例字体中非常小)不会,并且在字母限制方面会被忽略 这个问题是相关的,但不一样;例如,在该函数将变为例如“123456->1.23k”(“123.5k”为5个字母)的地方,我正在寻找执行“123456->0.1m”(“0[.1m”为3个字母)的东西。例如,这将是希望函数的输出(左原始,右理想返回值): 谢谢 更新:谢谢

在JavaScript中,如何编写一个函数,将给定的[edit:正整数]数字(1000亿以下)转换为3个字母的缩写——其中0-9和a-z/a-z作为一个字母计算,但点(因为它在许多比例字体中非常小)不会,并且在字母限制方面会被忽略

这个问题是相关的,但不一样;例如,在该函数将变为例如“123456->1.23k”(“123.5k”为5个字母)的地方,我正在寻找执行“123456->0.1m”(“0[.1m”为3个字母)的东西。例如,这将是希望函数的输出(左原始,右理想返回值):

谢谢

更新:谢谢!当进行以下修改时,答案在中,并且符合要求:

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortValue = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}
函数编号(值){
var newValue=价值;
如果(值>=1000){
变量后缀=[“”,“k”,“m”,“b”,“t”];
变量suffixNum=数学地板((“”+值).length/3);
var shortValue=“”;
对于(变量精度=2;精度>=1;精度--){
shortValue=parseFloat((suffixNum!=0)(value/Math.pow(1000,suffixNum)):value.toPrecision(precision));
var dotlesshortvalue=(shortValue++'')。替换(/[^a-zA-Z 0-9]+//g'');
如果(dotlesshortvalue.length)基于我在的答案,您的答案实际上略短一些,可以使用
.substring(0,3)

(和往常一样,除非您确切知道自己在做什么,否则不要使用数学;分配
var-pow=…
等会导致疯狂的错误。有关更安全的方法,请参阅链接。)


如果您对3个字符的要求很严格,那么您需要抓住结果>=1万亿的情况,否则您就有可能创建损坏的数据,这将非常糟糕。

我相信ninjagecko的解决方案并不完全符合您想要的标准。以下函数可以:

function intToString (value) {
    var suffixes = ["", "k", "m", "b","t"];
    var suffixNum = Math.floor((""+value).length/3);
    var shortValue = parseFloat((suffixNum != 0 ? (value / Math.pow(1000,suffixNum)) : value).toPrecision(2));
    if (shortValue % 1 != 0) {
        shortValue = shortValue.toFixed(1);
    }
    return shortValue+suffixes[suffixNum];
}
对于大于99万亿的值,将不添加字母,这可以通过添加到“后缀”数组轻松修复

由Philipp编辑如下:经过以下更改,它完全符合所有要求

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortValue = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}
函数编号(值){
var newValue=价值;
如果(值>=1000){
变量后缀=[“”,“k”,“m”,“b”,“t”];
变量suffixNum=数学地板((“”+值).length/3);
var shortValue=“”;
对于(变量精度=2;精度>=1;精度--){
shortValue=parseFloat((suffixNum!=0)(value/Math.pow(1000,suffixNum)):value.toPrecision(precision));
var dotlesshortvalue=(shortValue++'')。替换(/[^a-zA-Z 0-9]+//g'');

if(dotlesshortvalue.length这也可以处理非常大的值,并且更加简洁高效

abbreviate_number = function(num, fixed) {
  if (num === null) { return null; } // terminate early
  if (num === 0) { return '0'; } // terminate early
  fixed = (!fixed || fixed < 0) ? 0 : fixed; // number of decimal places to show
  var b = (num).toPrecision(2).split("e"), // get power
      k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions
      c = k < 1 ? num.toFixed(0 + fixed) : (num / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power
      d = c < 0 ? c : Math.abs(c), // enforce -0 is 0
      e = d + ['', 'K', 'M', 'B', 'T'][k]; // append power
  return e;
}
缩写_number=函数(num,固定){
如果(num==null){return null;}//提前终止
如果(num==0){return'0';}//提前终止
fixed=(!fixed | | fixed<0)?0:fixed;//要显示的小数位数
var b=(num).toPrecision(2).split(“e”),//获取功率
k=b.length===1?0:Math.floor(Math.min(b[1].slice(1),14)/3),//小数点处的地板,万亿的天花板
c=k<1?num.toFixed(0+固定):(num/Math.pow(10,k*3)).toFixed(1+固定),//除以幂
d=c<0?c:Math.abs(c),//强制-0是0
e=d+[''K','M','B','T'][K];//附加功率
返回e;
}
结果:

for(var a='', i=0; i < 14; i++){ 
    a += i; 
    console.log(a, abbreviate_number(parseInt(a),0)); 
    console.log(-a, abbreviate_number(parseInt(-a),0)); 
}

0 0
-0 0
01 1
-1 -1
012 12
-12 -12
0123 123
-123 -123
01234 1.2K
-1234 -1.2K
012345 12.3K
-12345 -12.3K
0123456 123.5K
-123456 -123.5K
01234567 1.2M
-1234567 -1.2M
012345678 12.3M
-12345678 -12.3M
0123456789 123.5M
-123456789 -123.5M
012345678910 12.3B
-12345678910 -12.3B
01234567891011 1.2T
-1234567891011 -1.2T
0123456789101112 123.5T
-123456789101112 -123.5T
012345678910111213 12345.7T
-12345678910111212 -12345.7T
for(var a='',i=0;i<14;i++){
a+=i;
log(a,缩写_编号(parseInt(a),0));
log(-a,缩写_编号(parseInt(-a),0));
}
0 0
-0 0
01 1
-1 -1
012 12
-12 -12
0123 123
-123 -123
012341.2K
-1234-1.2K
012345 12.3K
-12345-12.3K
0123456123.5K
-123456-123.5K
01234567 1.2M
-1234567-1.2M
012345678 12.3M
-12345678-12.3M
0123456789 123.5M
-123456789-123.5M
012345678910 12.3B
-12345678910-12.3B
01234567891011 1.2吨
-1234567891011-1.2吨
0123456789101112 123.5T
-12345678910112-123.5T
012345678910111213 12345.7吨
-1234567891011212-12345.7吨

经过一番尝试后,这种方法似乎达到了要求的标准。从@chuckator的答案中获得了一些灵感

function abbreviateNumber(value) {

    if (value <= 1000) {
        return value.toString();
    }

    const numDigits = (""+value).length;
    const suffixIndex = Math.floor(numDigits / 3);

    const normalisedValue = value / Math.pow(1000, suffixIndex);

    let precision = 2;
    if (normalisedValue < 1) {
        precision = 1;
    }

    const suffixes = ["", "k", "m", "b","t"];
    return normalisedValue.toPrecision(precision) + suffixes[suffixIndex];
}
函数编号(值){

如果(值我想你不能试试这个

如果你想把1000换成1k

console.log(numeral(1000).format('0a'));
如果你想把123400转换成123.4k,试试这个

console.log(numeral(123400).format('0.0a'));

Intl是用于实现国际化行为的Javascript标准“包”。Intl.NumberFormatter特别是本地化的数字格式化程序。因此,此代码实际上尊重您在本地配置的千和十进制分隔符

intlFormat(num) {
    return new Intl.NumberFormat().format(Math.round(num*10)/10);
}

abbreviateNumber(value) {
    let num = Math.floor(value);
    if(num >= 1000000000)
        return this.intlFormat(num/1000000000)+'B';
    if(num >= 1000000)
        return this.intlFormat(num/1000000)+'M';
    if(num >= 1000)
        return this.intlFormat(num/1000)+'k';
    return this.intlFormat(num);
}
缩写数字(99999999999)//给出999B

相关问题:


警报(逆数(10000000000));

我认为这是一个相当优雅的解决方案。它不尝试处理负数:

const COUNT_ABBRS = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];

function formatCount(count, withAbbr = false, decimals = 2) {
    const i     = 0 === count ? count : Math.floor(Math.log(count) / Math.log(1000));
    let result  = parseFloat((count / Math.pow(1000, i)).toFixed(decimals));
    if(withAbbr) {
        result += `${COUNT_ABBRS[i]}`; 
    }
    return result;
}
   formatCount(1000, true);
=> '1k'
   formatCount(100, true);
=> '100'
   formatCount(10000, true);
=> '10k'
   formatCount(10241, true);
=> '10.24k'
   formatCount(10241, true, 0);
=> '10k'
   formatCount(10241, true, 1)
=> '10.2k'
   formatCount(1024111, true, 1)
=> '1M'
   formatCount(1024111, true, 2)
=> '1.02M'
示例

const COUNT_ABBRS = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];

function formatCount(count, withAbbr = false, decimals = 2) {
    const i     = 0 === count ? count : Math.floor(Math.log(count) / Math.log(1000));
    let result  = parseFloat((count / Math.pow(1000, i)).toFixed(decimals));
    if(withAbbr) {
        result += `${COUNT_ABBRS[i]}`; 
    }
    return result;
}
   formatCount(1000, true);
=> '1k'
   formatCount(100, true);
=> '100'
   formatCount(10000, true);
=> '10k'
   formatCount(10241, true);
=> '10.24k'
   formatCount(10241, true, 0);
=> '10k'
   formatCount(10241, true, 1)
=> '10.2k'
   formatCount(1024111, true, 1)
=> '1M'
   formatCount(1024111, true, 2)
=> '1.02M'
代码

const SI_PREFIXES = [
  { 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' },
]

const abbreviateNumber = (number) => {
  if (number === 0) return number

  const tier = SI_PREFIXES.filter((n) => number >= n.value).pop()
  const numberFixed = (number / tier.value).toFixed(1)

  return `${numberFixed}${tier.symbol}`
}

abbreviateNumber(2000) // "2.0k"
abbreviateNumber(2500) // "2.5k"
abbreviateNumber(255555555) // "255.6M"
import abbreviateNumber from './abbreviate-number'

test('abbreviateNumber', () => {
  expect(abbreviateNumber(0)).toBe('0')
  expect(abbreviateNumber(100)).toBe('100')
  expect(abbreviateNumber(999)).toBe('999')

  expect(abbreviateNumber(1000)).toBe('1.0k')
  expect(abbreviateNumber(100000)).toBe('100.0k')
  expect(abbreviateNumber(1000000)).toBe('1.0M')
  expect(abbreviateNumber(1e6)).toBe('1.0M')
  expect(abbreviateNumber(1e10)).toBe('10.0G')
  expect(abbreviateNumber(1e13)).toBe('10.0T')
  expect(abbreviateNumber(1e16)).toBe('10.0P')
  expect(abbreviateNumber(1e19)).toBe('10.0E')

  expect(abbreviateNumber(1500)).toBe('1.5k')
  expect(abbreviateNumber(1555)).toBe('1.6k')

  expect(abbreviateNumber(undefined)).toBe('0')
  expect(abbreviateNumber(null)).toBe(null)
  expect(abbreviateNumber('100')).toBe('100')
  expect(abbreviateNumber('1000')).toBe('1.0k')
})
测试:

const SI_PREFIXES = [
  { 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' },
]

const abbreviateNumber = (number) => {
  if (number === 0) return number

  const tier = SI_PREFIXES.filter((n) => number >= n.value).pop()
  const numberFixed = (number / tier.value).toFixed(1)

  return `${numberFixed}${tier.symbol}`
}

abbreviateNumber(2000) // "2.0k"
abbreviateNumber(2500) // "2.5k"
abbreviateNumber(255555555) // "255.6M"
import abbreviateNumber from './abbreviate-number'

test('abbreviateNumber', () => {
  expect(abbreviateNumber(0)).toBe('0')
  expect(abbreviateNumber(100)).toBe('100')
  expect(abbreviateNumber(999)).toBe('999')

  expect(abbreviateNumber(1000)).toBe('1.0k')
  expect(abbreviateNumber(100000)).toBe('100.0k')
  expect(abbreviateNumber(1000000)).toBe('1.0M')
  expect(abbreviateNumber(1e6)).toBe('1.0M')
  expect(abbreviateNumber(1e10)).toBe('10.0G')
  expect(abbreviateNumber(1e13)).toBe('10.0T')
  expect(abbreviateNumber(1e16)).toBe('10.0P')
  expect(abbreviateNumber(1e19)).toBe('10.0E')

  expect(abbreviateNumber(1500)).toBe('1.5k')
  expect(abbreviateNumber(1555)).toBe('1.6k')

  expect(abbreviateNumber(undefined)).toBe('0')
  expect(abbreviateNumber(null)).toBe(null)
  expect(abbreviateNumber('100')).toBe('100')
  expect(abbreviateNumber('1000')).toBe('1.0k')
})

我用这个函数来得到这些值

function Converter(number, fraction) {
    let ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'K' },
      { divider: 1e6, suffix: 'M' },
      { divider: 1e9, suffix: 'G' },
      { divider: 1e12, suffix: 'T' },
      { divider: 1e15, suffix: 'P' },
      { divider: 1e18, suffix: 'E' },
    ]
    //find index based on number of zeros
    let index = (Math.abs(number).toString().length / 3).toFixed(0)
    return (number / ranges[index].divider).toFixed(fraction) + ranges[index].suffix
}
每3个数字都有不同的后缀,这是我首先要找到的

因此,删除负号(如果存在),然后找出这个数字中有多少个3位数

之后,根据之前的计算找到合适的后缀添加到除数中

Converter(1500, 1)
将返回:

1.5K
@尼美沙姆

您的解决方案不适用于以下情况:

Input 50000
Output 50.0k

下面的解决方案很好

const convertNumberToShortString = (
  number: number,
  fraction: number
) => {
  let newValue: string = number.toString();
  if (number >= 1000) {
    const ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'k' },
      { divider: 1e6, suffix: 'm' },
      { divider: 1e9, suffix: 'b' },
      { divider: 1e12, suffix: 't' },
      { divider: 1e15, suffix: 'p' },
      { divider: 1e18, suffix: 'e' }
    ];
    //find index based on number of zeros
    const index = Math.floor(Math.abs(number).toString().length / 3);
    let numString = (number / ranges[index].divider).toFixed(fraction);
    numString =
      parseInt(numString.substring(numString.indexOf('.') + 1)) === 0
        ? Math.floor(number / ranges[index].divider).toString()
        : numString;
    newValue = numString + ranges[index].suffix;
  }
  return newValue;
};

// Input 50000
// Output 50k
// Input 4500
// Output 4.5k

直截了当的方法具有最好的可读性,并且使用最少的内存。无需过度使用正则表达式、映射对象、数学对象、for循环等

用K格式化现金值
const formatCash=n=>{
如果(n<1e3)返回n;
如果(n>=1e3)返回+(n/1e3).toFixed(1)+“K”;
};

console.log(formatCash(2500));
这是另一种用法。I
var numbers = [98721, 9812730,37462,29,093484620123, 9732,0283737718234712]
for(let num of numbers){
  console.log(new Intl.NumberFormat( 'en-US', { maximumFractionDigits: 1,notation: "compact" , compactDisplay: "short" }).format(num));
}
98.7K
9.8M
37.5K
29
93.5B
9.7K
283.7T
const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3 && n < 1e5) return +(n / 1e3).toFixed(1) + "K";
  if (n >= 1e5 && n <= 1e6) return +(n / 1e5).toFixed(1) + "L";
  if (n >= 1e6 && n <= 1e9) return +(n / 1e7).toFixed(1) + "C";
};
if (num >= 1e3 !& num >= 1e6) {num2 = num/1e3 + "K";};
if (num >= 1e6 !& num >= 1e9) {num2 = num/1e6 + "M";};
if (num >= 1e9 !& num >= 1e12) {num2 = num/1e9 + "B";};
if (num >= 1e12 !& num >= 1e15) {num2 = num/1e12 + "T";};
if (num >= 1e15 !& num >= 1e18) {num2 = num/1e15 + "Qa";};
if (num >= 1e18 !& num >= 1e21) {num2 = num/1e18 + "Qi";};
if (num >= 1e21 !& num >= 1e24) {num2 = num/1e21 + "Sx";};
if (num >= 1e24 !& num >= 1e27) {num2 = num/1e24 + "Sp";};
if (num >= 1e27 !& num >= 1e30) {num2 = num/1e27 + "Oc";};
if (num >= 1e30 !& num >= 1e93) {num2 = num/1e30 + "No";};
if (num >= 1e33 !& num >= 1e36) {num2 = num/1e33 + "Dc";};
if (num >= 1e36 !& num >= 1e39) {num2 = num/1e36 + "UDc";};
if (num >= 1e39) {num2 = num/1e39 + "DDc";};