Converting integers to ordinals
When dealing with dates, it's not uncommon to need to convert an integer into an ordinal number (1st, 2nd, 3rd, etc.). While making improvements to Mango recently I wrote a function to do this, first in Python, later in JavaScript.
Python
def ordinal(n): if 10 < n < 14: return u'%sth' % n if n % 10 == 1: return u'%sst' % n if n % 10 == 2: return u'%snd' % n if n % 10 == 3: return u'%srd' % n return u'%sth' % n
JavaScript
function ordinal(n) { if (10 < n && n < 14) return n + 'th'; switch (n % 10) { case 1: return n + 'st'; case 2: return n + 'nd'; case 3: return n + 'rd'; default: return n + 'th'; } }
By special-casing 11, 12, and 13, the function becomes incredibly simple.
I'm pleased to have found a context in which JavaScript's switch statement
is almost elegant. The problem, usually, is the need to break to prevent
fall-through. When used within a function, though, the return statement is
able to perform this role, making the JavaScript code almost as readable as
the Python equivalent.
Possibly related posts
- Self-caching functions in JavaScript and Python
- Python loops can have else clause?!
- Filtering lists in Python, Ruby, and JavaScript
- Repeating strings in JavaScript
- Bitwise NOT operator proves useful in JavaScript
Comments
David:
Thanks for this. It's definitely simple and elegant. Much better than any other ordinal method I've seen. The only suggestion I would make is to allow for negative numbers. Personally, I can't think of a good use case, but I don't like that it's a limitation of the function.
It's a very easy mod … just get the absolute value of the number (which we'll test against), then return the original number + ordinal value:
Number.prototype.ordinal = function() {
var n = Math.abs(this);
if (10 < n && n < 14) return this + 'th';
switch (n % 10) {
case 1: return this + 'st';
case 2: return this + 'nd';
case 3: return this + 'rd';
default: return this + 'th';
}
};