Now Available in YourJS

When dealing with numbers, at times for presentation’s sake, we need to add ordinals to numbers. For example, instead of today is the “September 28”, you may want to say that it is the “28th of September”. I wrote the following code snippet to easily add the ordinal for any integer in JavaScript:


(function(o) {
  Number.getOrdinalFor = function(intNum, includeNumber) {
    return (includeNumber ? intNum : "")
      + (o[((intNum = Math.abs(intNum % 100)) - 20) % 10] || o[intNum] || "th");
  };
})([,"st","nd","rd"]);

Description

Gets the appropriate ordinal (“st”, “nd”, “rd”, or “th”) for the specified integer.

Parameters

  1. intNum:
    The number for which the ordinal will be produced.
  2. includeNumber:
    The value that is evaluated as a boolean to determine whether or not to include the specified integer in the returned string. This is optional and thusly defaults to false.

Returns

The string containing the ordinal for the specified integer. If the second parameter evaluates to true, the specified number will returned with the ordinal appended to it.

Examples

The following shows how you could call this function:


var num1 = 1,
    num2 = 12,
    num3 = 123,
    num4 = 1432;
var str1 = Number.getOrdinalFor(num1, true), // 1st
    str2 = Number.getOrdinalFor(num2, true), // 12th
    str3 = Number.getOrdinalFor(num3, true), // 123rd
    str4 = Number.getOrdinalFor(num4, true); // 1432nd

You could even get a little fancy and run this on all of the numbers in a string by doing something like the following:


var str = "1, 2, and 3 place will get medals while 4 and later will get Cinnabons.";
alert(str.replace(/(\d+)/g, Number.getOrdinalFor));

The reason the above example works is because the first parameter that is passed into the function is the entire match, which in this case is the number found. The second parameter passed is the exact same thing, which since it is a string of one or more characters, will always evaluate to true. Having these two circumstances in mind, in every case that a number is found, the same number with the appropriate ordinal is replaces the number in the string.

You could modify it a bit to make it work with any numbers by doing something like this:


var str = "1, 2, 3, 4.5, 6, and 7.8 are all numbers.";
alert(str.replace(/\d*\.\d+|(\d+)/g, function(match, int) {
  return int
    ? Number.getOrdinalFor(parseInt(int, 10), 1)
    : match;
}));

I will not go into detail and explain why the above works. If you don’t understand it, I suggest, if you want to become really proficient in the language, that you dissect the code. Many times, if we try things out ourselves, we will be more likely to remember and understand why something works and when we can use something like that again. Of course, if you do get to a point where you just don’t understand something, leave a comment below and I will help you out. Have fun!!!


11 Comments

ildar · September 29, 2012 at 2:37 AM

var ords = {
1: ‘st’,
2: ‘nd’,
3: ‘rd’
};

function ordinal(n)
{
return ords[n % 100] || ‘th’;
};

    Chris West · September 29, 2012 at 9:13 PM

    Try putting in 11, 12, 13, 111, 112, 113, etc. Unfortunately, it will not work for this reason. I appreciate the try at simplicity though.

      Andy · July 15, 2013 at 9:27 AM

      [11,12,13,111,112,113].map(function(i) { return i+ ordinal(i); });
      [“11th”, “12th”, “13th”, “111th”, “112th”, “113th”]

      The problem?

        Chris West · August 21, 2018 at 3:45 PM

        Sorry, I believe that when I originally answered I didn’t state the issue clearly haha. I should’ve said that numbers such as the following will cause an issue:
        21, 22, 23, 31, 32, 33, etc.

        The issue is that instead of getting “21th” for 21 we should get “21st”. For that reason I am also modding by 10.

ildar · September 29, 2012 at 2:51 AM

As you can see this code above is very simplified just to show the main idea: less dividing, less comparing, less coding, faster running, more knowing, better reading. 🙂

    Chris West · September 29, 2012 at 9:14 PM

    See my reply to that comment. I do appreciate the effort.

    Chris West · August 21, 2018 at 3:45 PM

    Sorry, I believe that when I originally answered I didn’t state the issue clearly haha. I should’ve said that numbers such as the following will cause an issue:
    21, 22, 23, 31, 32, 33, etc.

    The issue is that instead of getting “21th” for 21 we should get “21st”. For that reason I am also modding by 10.

John P. · December 11, 2012 at 5:59 PM

An ordinal function in as few characters as I could manage, for the lolz.

function ordinal(x){return x+(~~(x/10)%10==1?’th’:[,’st’,’nd’,’rd’][x%10]||’th’)}

Works for integers >= 0.

Andy · July 15, 2013 at 9:46 AM

function suffix(n) {
n = (+n % 100).toString().split(”);
return (n[0] === ‘1’ || +n[0] > 3) ? ‘th’ : [‘st’, ‘nd’, ‘rd’][(+n[1])-1];
};

    Andy · July 15, 2013 at 9:47 AM

    Should have been:

    function suffix(n) {
    n = (+n % 100).toString().split(”);
    return (n[0] === ‘1’ || +n[1] > 3) ? ‘th’ : [‘st’, ‘nd’, ‘rd’][(+n[1])-1];
    };

      Andy · July 15, 2013 at 10:12 AM

      Wrong again ¬_¬

      function suffix(n) {
      n = (+n % 100).toString().split(”);
      return (n.length > 1 && n.shift() === ‘1’ || +n[0] > 3) ? ‘th’ : [‘th’, ‘st’, ‘nd’, ‘rd’][(+n[0])];
      };

Leave a Reply

Your email address will not be published. Required fields are marked *