Built-in way to convert Integer to Ordinal String
The coolest way is to check the answer to this question by David Carraher. I am shamelessly stealing his code here to write a function that gives you rules for up to maxNumber
:
ordinalRule[maxNumber_Integer] /; maxNumber > 0 :=
Block[{p},
Thread[
Function[{x},
x -> StringSplit[SpokenString[p[[#]]]][[2]] &[x] // Quiet] /@ Range[maxNumber]
]];
For example:
ordinalRule[100]
(*out*){1 -> "1st", 2 -> "2nd", 3 -> "3rd", 4 -> "4th", 5 -> "5th",
6 -> "6th", 7 -> "7th", 8 -> "8th", 9 -> "9th", 10 -> "10th",
11 -> "11th", 12 -> "12th", 13 -> "13th", 14 -> "14th", 15 -> "15th",
16 -> "16th", 17 -> "17th", 18 -> "18th", 19 -> "19th",
20 -> "20th", 21 -> "21st", 22 -> "22nd", 23 -> "23rd", 24 -> "24th",
25 -> "25th", 26 -> "26th", 27 -> "27th", 28 -> "28th",
29 -> "29th", 30 -> "30th", 31 -> "31st", 32 -> "32nd", 33 -> "33rd",
34 -> "34th", 35 -> "35th", 36 -> "36th", 37 -> "37th",
38 -> "38th", 39 -> "39th", 40 -> "40th", 41 -> "41st", 42 -> "42nd",
43 -> "43rd", 44 -> "44th", 45 -> "45th", 46 -> "46th",
47 -> "47th", 48 -> "48th", 49 -> "49th", 50 -> "50th", 51 -> "51st",
52 -> "52nd", 53 -> "53rd", 54 -> "54th", 55 -> "55th",
56 -> "56th", 57 -> "57th", 58 -> "58th", 59 -> "59th", 60 -> "60th",
61 -> "61st", 62 -> "62nd", 63 -> "63rd", 64 -> "64th",
65 -> "65th", 66 -> "66th", 67 -> "67th", 68 -> "68th", 69 -> "69th",
70 -> "70th", 71 -> "71st", 72 -> "72nd", 73 -> "73rd",
74 -> "74th", 75 -> "75th", 76 -> "76th", 77 -> "77th", 78 -> "78th",
79 -> "79th", 80 -> "80th", 81 -> "81st", 82 -> "82nd",
83 -> "83rd", 84 -> "84th", 85 -> "85th", 86 -> "86th", 87 -> "87th",
88 -> "88th", 89 -> "89th", 90 -> "90th", 91 -> "91st",
92 -> "92nd", 93 -> "93rd", 94 -> "94th", 95 -> "95th", 96 -> "96th",
97 -> "97th", 98 -> "98th", 99 -> "99th", 100 -> "100th"}
I don't know whether this counts as built-in though.
----EDIT----
From @Wreach's comment: there is an undocumented built-in (that SpokenString
calls when dealing with numbers to ordinals) that does exactly that:
Speak["stackexchange"];
SpokenStringDump`SpeakOrdinal[121]
(*out*) 121st
In v10 I need to call Speak
before the relevant function auto-loads.
I noticed only afterwards that you were asking for a built-in method. I'm not certain if you would actually want to rely on an undocumented feature instead of writing your own, since it's not hard.
This requires v10 for StringTemplate
. It could be replaced with something else, of course...
Range[120] /.
{ tens_Integer /; Floor[Mod[tens, 100], 10] == 10 :> StringTemplate["`1`th"][tens],
firsts_Integer /; Mod[firsts, 10] == 1 :> StringTemplate["`1`st"][firsts],
seconds_Integer /; Mod[seconds, 10] == 2 :> StringTemplate["`1`nd"][seconds],
thirds_Integer /; Mod[thirds, 10] == 3 :> StringTemplate["`1`rd"][thirds],
rest_Integer :> StringTemplate["`1`th"][rest] }
(* { "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th",
"10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th",
"18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th",
"26th", "27th", "28th", "29th", "30th", "31st", "32nd", "33rd",
"34th", "35th", "36th", "37th", "38th", "39th", "40th", "41st",
"42nd", "43rd", "44th", "45th", "46th", "47th", "48th", "49th",
"50th", "51st", "52nd", "53rd", "54th", "55th", "56th", "57th",
"58th", "59th", "60th", "61st", "62nd", "63rd", "64th", "65th",
"66th", "67th", "68th", "69th", "70th", "71st", "72nd", "73rd",
"74th", "75th", "76th", "77th", "78th", "79th", "80th", "81st",
"82nd", "83rd", "84th", "85th", "86th", "87th", "88th", "89th",
"90th", "91st", "92nd", "93rd", "94th", "95th", "96th", "97th",
"98th", "99th", "100th", "101st", "102nd", "103rd", "104th",
"105th", "106th", "107th", "108th", "109th", "110th", "111th",
"112th", "113th", "114th", "115th", "116th", "117th", "118th",
"119th", "120th" } *)
A brute force but very simple approach (no undocumented functions needed) that I think will work with any version of Mathematica.
ordinalRule[n_Integer /; Mod[n, 100] == 11] := generalRule[n]
ordinalRule[n_Integer /; Mod[n, 100] == 12] := generalRule[n]
ordinalRule[n_Integer /; Mod[n, 100] == 13] := generalRule[n]
ordinalRule[n_Integer /; Mod[n, 10] == 1] = specialRule1[n];
ordinalRule[n_Integer /; Mod[n, 10] == 2] = specialRule2[n];
ordinalRule[n_Integer /; Mod[n, 10] == 3] = specialRule3[n];
ordinalRule[n_Integer] = generalRule[n];
specialRule1[n_] := n -> (ToString[n] <> "st")
specialRule2[n_] := n -> (ToString[n] <> "nd")
specialRule3[n_] := n -> (ToString[n] <> "rd")
generalRule[n_] := n -> (ToString[n] <> "th")
ordinalRule /@ Range @ 130
{1 -> "1st", 2 -> "2nd", 3 -> "3rd", 4 -> "4th", 5 -> "5th", 6 -> "6th", 7 -> "7th", 8 -> "8th", 9 -> "9th", 10 -> "10th", 11 -> "11th", 12 -> "12th", 13 -> "13th", 14 -> "14th", 15 -> "15th", 16 -> "16th", 17 -> "17th", 18 -> "18th", 19 -> "19th", 20 -> "20th", 21 -> "21st", 22 -> "22nd", 23 -> "23rd", 24 -> "24th", 25 -> "25th", 26 -> "26th", 27 -> "27th", 28 -> "28th", 29 -> "29th", 30 -> "30th", 31 -> "31st", 32 -> "32nd", 33 -> "33rd", 34 -> "34th", 35 -> "35th", 36 -> "36th", 37 -> "37th", 38 -> "38th", 39 -> "39th", 40 -> "40th", ... 91 -> "91st", 92 -> "92nd", 93 -> "93rd", 94 -> "94th", 95 -> "95th", 96 -> "96th", 97 -> "97th", 98 -> "98th", 99 -> "99th", 100 -> "100th", 101 -> "101st", 102 -> "102nd", 103 -> "103rd", 104 -> "104th", 105 -> "105th", 106 -> "106th", 107 -> "107th", 108 -> "108th", 109 -> "109th", 110 -> "110th", 111 -> "111th", 112 -> "112th", 113 -> "113th", 114 -> "114th", 115 -> "115th", 116 -> "116th", 117 -> "117th", 118 -> "118th", 119 -> "119th", 120 -> "120th", 121 -> "121st", 122 -> "122nd", 123 -> "123rd", 124 -> "124th", 125 -> "125th", 126 -> "126th", 127 -> "127th", 128 -> "128th", 129 -> "129th", 130 -> "130th"}