Convert long number into abbreviated string in JavaScript, with a special shortness requirement

前端 未结 16 2179
名媛妹妹
名媛妹妹 2020-11-30 22:33

In JavaScript, how would one write a function that converts a given [edit: positive integer] number (below 100 billion) into a 3-letter abbreviation -- where 0-9 an

相关标签:
16条回答
  • 2020-11-30 22:39

    Intl is the Javascript standard 'package' for implemented internationalized behaviours. Intl.NumberFormatter is specifically the localized number formatter. So this code actually respects your locally configured thousands and decimal separators.

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

    abbreviateNumber(999999999999) // Gives 999B

    Related question: Abbreviate a localized number in JavaScript for thousands (1k) and millions (1m)

    0 讨论(0)
  • 2020-11-30 22:43

    A lot of answers on this thread get rather complicated, using Math objects, map objects, for-loops, etc. But those approaches don't actually improve the design very much - they introduce more lines of code, more complexity, and more memory overhead. After evaluating several approaches, I think the manual approach is the easiest to understand, and provides the highest performance.

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

    0 讨论(0)
  • 2020-11-30 22:44
                function converse_number (labelValue) {
    
                        // Nine Zeroes for Billions
                        return Math.abs(Number(labelValue)) >= 1.0e+9
    
                        ? Math.abs(Number(labelValue)) / 1.0e+9 + "B"
                        // Six Zeroes for Millions 
                        : Math.abs(Number(labelValue)) >= 1.0e+6
    
                        ? Math.abs(Number(labelValue)) / 1.0e+6 + "M"
                        // Three Zeroes for Thousands
                        : Math.abs(Number(labelValue)) >= 1.0e+3
    
                        ? Math.abs(Number(labelValue)) / 1.0e+3 + "K"
    
                        : Math.abs(Number(labelValue));
    
                    }
    

    alert(converse_number(100000000000));

    0 讨论(0)
  • 2020-11-30 22:45

    Here's what I think is a fairly elegant solution. It does not attempt to deal with negative numbers:

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

    Examples:

       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'
    
    0 讨论(0)
  • 2020-11-30 22:46

    Code

    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"
    

    Test:

    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')
    })
    
    0 讨论(0)
  • 2020-11-30 22:50

    I think you cant try this numeraljs/

    If you want convert 1000 to 1k

    console.log(numeral(1000).format('0a'));
    

    and if you want convert 123400 to 123.4k try this

    console.log(numeral(123400).format('0.0a'));
    
    0 讨论(0)
提交回复
热议问题