In Javascript it's usually considered best practice to work with absolute numbers, as number
is a defined type. However, when expressing these numbers in user interfaces, it's more likely we'll want to express them differently. For example, consider I have the following list of numbers. I want to still store them as numbers, but then add nd
, st
, rd
, or th
when showing them to the user:
let x = [ 1, 13, 22, 100, 1204, 133 ];
I could of course do this manually, and store each number of a specific prefix, or define custom rules, but this gets a little messy - and what if I need to support multiple languages. Although in english we write 3rd
to represent 3rd
place, this may not be the same in other languages.
Fortunately there is a solution in Javascript - the use of Intl.PluralRules
. This will define plural rules based on locale:
let plurals = Intl.PluralRules();
let x = plurals.select(0) // Returns "other"
let y = plurals.select(1) // Returns "one"
let z = plurals.select(2) // Returns "other"
By default, PluralRules
is configured as cardinal
, which means anything above 1 is considered plural. Above, as you can see, PluralRules
lets us differentiate whether a number is plural or not.
Things get more interesting when we set it to ordinal
, which takes into consideration the ways we use numbers. Here, it will tell us language specific rules on how to handle each number - so we can do things like 2nd
, 3rd
, and 4th
const plurals = new Intl.PluralRules('en-US', { type: 'ordinal' });
let a = plurals.select(0); // Returns "other"
let b = plurals.select(1); // Returns "one"
let c = plurals.select(2); // Returns "two"
let d = plurals.select(3); // Returns "few"
let e = plurals.select(4); // Returns "other"
Now we can customize our outputs based on locale, so we don't run into weird issues. Here, we're using en-US
, but any other valid locale will also work. To map our numbers to 1st
, 2nd
, 3rd
, etc, we only have to create a mapping like this:
let x = [ 1, 13, 22, 100, 1204, 133 ];
const plurals = new Intl.PluralRules('en-US', { type: 'ordinal' });
let pluralMapping = {
"one" : "st",
"two" : "nd",
"few" : "rd",
"other" : "th"
}
let y = [];
x.forEach((item) => {
let getPlural = plurals.select(item);
let pluralEnding = pluralMapping[getPlural]
y.push(`${item}${pluralEnding}`)
})
console.log(y); // ['1st', '13th', '22nd', '100th', '1204th', '133rd']