function nth(n){return["st","nd","rd"][((n+90)%100-10)%10-1]||"th"}
(this is for positive integers, see below for other variations)
Start with an array with the suffixes ["st", "nd", "rd"]
. We want to map integers ending in 1, 2, 3 (but not ending in 11, 12, 13) to the indexes 0, 1, 2.
Other integers (including those ending in 11, 12, 13) can be mapped to anything else—indexes not found in the array will evaluate to undefined
. This is falsy in javascript and with the use of logical or (|| "th"
) the expression will return "th"
for these integers, which is exactly what we want.
The expression ((n + 90) % 100 - 10) % 10 - 1
does the mapping. Breaking it down:
(n + 90) % 100
: This expression takes the input integer − 10 mod 100, mapping 10 to 0, ... 99 to 89, 0 to 90, ..., 9 to 99. Now the integers ending in 11, 12, 13 are at the lower end (mapped to 1, 2, 3).- 10
: Now 10 is mapped to −10, 19 to −1, 99 to 79, 0 to 80, ... 9 to 89. The integers ending in 11, 12, 13 are mapped to negative integers (−9, −8, −7).% 10
: Now all integers ending in 1, 2, or 3 are mapped to 1, 2, 3. All other integers are mapped to something else (11, 12, 13 are still mapped to −9, −8, −7).- 1
: Subtracting one gives the final mapping of 1, 2, 3 to 0, 1, 2.function nth(n){return["st","nd","rd"][((n+90)%100-10)%10-1]||"th"}_x000D_
_x000D_
//test integers from 1 to 124_x000D_
for(var r = [], i = 1; i < 125; i++) r.push(i + nth(i));_x000D_
_x000D_
//output result_x000D_
document.getElementById('result').innerHTML = r.join('<br>');
_x000D_
<div id="result"></div>
_x000D_
Allowing negative integers:
function nth(n){return["st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10-1]||"th"}
In ES6 fat arrow syntax (anonymous function):
n=>["st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10-1]||"th"
An even shorter alternative for positive integers is the expression
[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'
See this post for explanation.
[,'st','nd','rd'][n/10%10^1&&n%10]||'th'