JavaScript number to short format like YouTube view counts, with magnitude suffix

problem

I needed to format numbers to a short format, like '12K', '7.2M', the same way YouTube view counts are formatted. So a magnitude suffix should be added: K, M, or B, for thousands, millions, and billions, respectively.

For numbers that will get to a single digit, one digit after the decimal point should be specified, if applicable.

This is the desired end result:

  • 12 -> 12
  • 123 -> 123
  • 1,234 -> 1.2K
  • 12,345 -> 12K
  • 123,456 -> 123K
  • 1,234,567 -> 1,2M
  • 12,345,678 -> 12M
  • 123,456,789 -> 123M
  • 1,234,567,890 -> 1,2B
  • 1,023,456,789 -> 1B
solution

I used a ranges array for the magnitude levels, and this is how the code turned out to be:

const ranges = [{
    divider: 1E3,
    suffix: 'K'
}, {
    divider: 1E6,
    suffix: 'M'
}, {
    divider: 1E9,
    suffix: 'B'
}];

function formatNumber(input) {
    for (let index = ranges.length - 1; index >= 0; index--) {
        if (input > ranges[index].divider) {
            let quotient = input / ranges[index].divider;

            if (quotient < 10) {
                quotient = Math.floor(quotient * 10) / 10;
            } else {
                quotient = Math.floor(quotient);
            }

            return quotient.toString() + ranges[index].suffix;
        }
    }

    return input.toString();
}

And this is how it looks like as an Angular pipe:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'formatNumberShortSuffix'
})
export class FormatNumberShortSuffixPipe implements PipeTransform {
    readonly ranges = [
        { divider: 1E3, suffix: 'K' },
        { divider: 1E6, suffix: 'M' },
        { divider: 1E9, suffix: 'B' }
    ];

    transform(input: number): string {
        for (let index = this.ranges.length - 1; index >= 0; index--) {
            if (input > this.ranges[index].divider) {
                let quotient = input / this.ranges[index].divider;

                if (quotient < 10) {
                    quotient = Math.floor(quotient * 10) / 10;
                } else {
                    quotient = Math.floor(quotient);
                }

                return quotient.toString() + this.ranges[index].suffix;
            }
        }

        return input.toString();
    }
}
Gravatar
Author: Dan Dumitru
Last Edit: May 14, 2020

Your Comment

Feel free to post additional info or improvement suggestions.
preview
Optional, never shown, displays gravatar.

Formatting Tips

This editor uses Markdown to easily add code in your posts.

Triple backticks for full line(s) of code (or indent 4 spaces)

```
let foo = 'bar';
```

[link text](http://a.com)

*italic* **bold**

More Tips