This exercise is kind of fun. For any given array of numbers, we want to return an array of ordinal numbers. For example, given an array of `[ 1, 2, 3 ]`, we want to return `[ '1st', '2nd', '3rd' ]`.

How do we do this?

As anything else, there are always a number of approaches:

1. Use a look-up array
2. Convert the number into an array, then check the last member
3. Use the built-in `Intl` object

Now, we’ll run the `Array.prototype.map()` function on our array of numbers, to return their ordinal counterparts:

The above will return:

Our code works, but we have an off-by-1 logical error in our code. In other words, instead of the given result, we need this array returned:

This is an easy fix:

Now we’re getting back the expected result. What we can conclude from the look-up array approach is that it will work great for smaller arrays of numbers. It’s a quick and easy solution when we need to convert a short array of numbers to its ordinal counterpart. However, how do we deal with longer arrays of numbers? What do we do if our array’s length is a lot larger, say, in the hundreds? For that we’ll use the second solution.

The second solution is Convert the number into an array, then check the last member. Let’s start from the core of this solution: instead of working on an array of numbers, we’ll work with a single number. So:

The above code works perfectly for a majority of cases. But what if a user types, for example, `4321`? This is the output:

This is obviously not the correct solution; it should have been `4321st`. So let’s take the number `4321` and convert it into an array:

Why are we getting the above error? Because the single dot after `4321` stands for the decimal delimiter. Luckily, the fix here is really easy:

Great, now we’re successfully splitting our number into an array of characters. Next, let’s log out only the last member of the array (i.e the last digit of our number):

Now let’s log out only the last member of the array, using:

Here’s the full updated code:

Now all we need to do is map the suffixes like this:

• if we get a `1`, we return `1st`
• if we get a `2`, we return `2nd`
• if we get a `3`, we return `3rd`

Here’s the updated code:

At this point, our task is seemingly finished, but there’s a weird edge case with teens. If we ran the above code and passed, for example, number `11` to the prompt, we’d get back: `11st`. This is wrong; we should have returned `11th`.

The solution for this is to check the last two digits instead of one. Then, if the last two digits are `11`, `12`, or `13`, we’ll return a `th` suffix, and for all other cases, we’ll return the appropriate `st`, `nd`, or `rd`.

Here’s the natural update to our code. Note: this code can be refactored; for now, let’s just think about the logic and not focus too much on optimizing our code.

Great, our code works fully, and also takes care of edge cases!

To confirm that that is really the case, we could test our improved code by passing random numbers on each function call: `4311`, `4312`, `4313`, `4321`, `101`, `111`, `1001`, `1011`, `1515`.

However, there’s even a better way to do it. We’ll simply write some code to run our `addOrdinalSuffix()` function on an array of numbers. Here’s the updated code:

Here’s the output of the above code:

Note:
This exercise comes from Book 3 of my book series on JS, available on Leanpub.com.