Getting Ordinal Suffixes in JavaScript

I was recently looking into formatting numbers in JavaScript, and had to format a number with its ordinal suffix. That is, getting the "st" suffix for "1st", "nd" suffix for "2nd", etc. It seems like it would be easy enough to do, and because it seems so easy to do, there are many answers on Stack Overflow with many different attempts.

Most of them are variations of this logic (don't do this):

function ordinal(n) {
  switch (n % 100) {
    case 11:
    case 12:
    case 13:
      return 'th';
  }
  switch (n % 10) {
    case 1:
      return 'st';
    case 2:
      return 'nd';
    case 3:
      return 'rd';
    default:
      return 'th';
  }
}

Unfortunately, this solution (and most of the answers on Stack Overflow) fails to account for negative numbers, so don't use it.

It might seem like a trivial issue, and it is trivially easy to solve, but there's an even better solution to this problem using native JS APIs.

Instead, Intl.PluralRules can be used to look up the proper suffixes without needing to know the underlying logic for English:

function ordinal(n) {
  const rules = new Intl.PluralRules('en-US', { type: 'ordinal' });
  switch (rules.select(n)) {
    case 'one':
      return 'st';
    case 'two':
      return 'nd';
    case 'few':
      return 'rd';
    default:
      return 'th';
  }
}

That's all there is to it. It's fast and painless and can be easily extended to externalize the lookup:

const rulesMap = new Map([
    ['one', 'st'],
    ['two', 'nd'],
    ['few', 'rd'],
    ['other', 'th']
]);
function ordinal(n) {
  const rules = new Intl.PluralRules('en-US', { type: 'ordinal' });
  return rulesMap.get(rules.select(n))
}

And could be extended to support multiple locales:

function ordinal(n, locale) {
  const rules = new Intl.PluralRules(locale, { type: 'ordinal' });
  ...