-
-
Save furf/986113 to your computer and use it in GitHub Desktop.
| function( | |
| a // number | |
| ){ | |
| return[ | |
| "th","st","nd","rd" // array of ordinal suffixes | |
| ][ | |
| (a=~~ // floor the value for usable index (integer) | |
| (a<0?-a:a) // absolute value for usable index (positive) | |
| %100) // mod 100 to ensure teens edge case is handled every century | |
| >10&&a<14 // handle teens edge case where 11-13 return "th" | |
| ||(a%=10) // mod 10 to check ones column digit | |
| >3 // all digits above 3 return "th" | |
| ?0 // return "th" for above cases | |
| :a // return "th", "st", "rd" for others | |
| ] | |
| } |
| function b(a){return["th","st","nd","rd"][(a=~~(a<0?-a:a)%100)>10&&a<14||(a%=10)>3?0:a]} |
| Copyright (c) 2011 Dave Furfero, http://furf.com | |
| Permission is hereby granted, free of charge, to any person obtaining | |
| a copy of this software and associated documentation files (the | |
| "Software"), to deal in the Software without restriction, including | |
| without limitation the rights to use, copy, modify, merge, publish, | |
| distribute, sublicense, and/or sell copies of the Software, and to | |
| permit persons to whom the Software is furnished to do so, subject to | |
| the following conditions: | |
| The above copyright notice and this permission notice shall be | |
| included in all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| { | |
| "name": "ordinal", | |
| "description": "Return the ordinal suffix for a number.", | |
| "keywords": ["ordinal","number","suffix","string"] | |
| } |
thanks! when i originally wrote this snippet, i included the value as well, but the second time i used it, i needed only the returned suffix to place inside a separate span, hidden for accessibility, while visually displaying the inning number (a constraint of the layout). also, a user might want to superscript the suffix. (you can see it in action by inspecting the inning number on the mlb.com homepage scoreboard.) i felt it provided the greater flexibility to exclude it and that it was easy enough to code "n + ordinal(n)" when needed. but for this application, i suppose i have quite a few characters left to make it optional. :)
instead of adding an option, maybe you could also return [num,ord]? that way it's easy enough to extract what you want.
ordinal(32)[1]
ordinal(32).join('')Interesting. I would prefer your syntax in the case where the value being passed is not stored.
32+ordinal(32) // looks a little sillyBut in other cases, that syntax would be longer. If I were to support the return of the value, the optional concatenation is more terse and provides a more traditional API.
// suffix-only usage
ordinal(n) // current suffix-only
ordinal(n)[1] // return [value, suffix] array
ordinal(n) // optional concatenation
// value-added usage
n+ordinal(n) // current suffix-only
ordinal(n).join('') // return [value, suffix] array
ordinal(n,1) // optional concatenationPS--I'm really digging the 140bytes project. Lots of good reads. Cheers!
My version.
function(a){return[,"st","nd","rd"][/1?.$/.exec(a)]||"th"}
i like the use of the empty array member. i avoided regexp for performance. http://jsperf.com/ordinals-in-140-bytes (this code actually runs on mlb.com :)) but in the world of code golf you win!
tsaniel's version add's a lot of overhead, buried in the 'regexp black-box'.
If it's code golf we play, then we can't allow ourselves defining a function to get us the decimal exponent:
d = function (i){var l=Math.log; return Math.ceil(l(i)/l(10))}
Here's a version using a map-reduce-like logic
current version here: https://gist.github.com/1308753
// JS converts string-numbers on the fly e.g. "7"&3 >3
// solution with a 'map-reduce' mindset
// similar and more concise solutions could be implemented
// a=(a+'').substr(-2);
ord = function (a){
//summary: cast to string, map (e.g. atomize) and reduce
a=(a+'') //cast to string
.split('') //atomize
.slice(-2) //get the last two elements
.reduce( //reduce arithmetically to a single value
function(a,b){
if(1==a) return 0; //teens case -> return 0 (#el containing 'th')
else return b>3 ? 0 : b; //if b>3 return 0 -> 'th'
}
);
return ['th','st','nd','rd'][a]; //map number to a string
};another difference between our implementations: mine is the only one to base ordinal suffix on the whole number, not the decimal. since ordinals are natural numbers [0, 1, 2, ...], i felt that the floor of the number was the meaningful part to transform. i could be wrong. i suppose it's a matter of semantics and usage which implementation works best.
so, in seeing these other implementations and thinking it through... in the case of a decimal being passed and the suffix returned being based on a transformation of the passed argument, then jed, your suggestion of returning [n, suffix] would be desirable where n is the floored number. (or n + suffix)
thanks for the posts, guys.
New version with a bitwise trick but only supports non-negative integers:
function(a){return[,'st','nd','rd'][a%100/10^1&&a%10]||'th'}
21th? 22th? 23th?
11st? 12nd? 13rd? Keep trying! :)
i like tsaniels bitwise the best for all practical purposes. non-negative integers are typically all you'll need.
fixd?
function(a){a+="";return(a.charAt(a.length-2)==1)?"th":[,"st","nd","rd"][a.charAt(a.length-1)]||"th"}
Edit:
made it shorter with "%"
function(a){return(a%100>10&&a%100<19)?"th":[,"st","nd","rd"][a%10]||"th"}
Edit:
I just noticed Tsaniel's function... it's shorter than mine, therefore, my function is useless... meh.
@furf: Did you mean you find a bug? But it just works fine with me.
@tsaniel no, he found a bug in my code, I deleted the original post. Your function is perfect.
Oh I see.
Shave another byte off by the way:
function(a){return[,'st','nd','rd'][a/10%10^1&&a%10]||'th'}
great work! just out of curiosity, why no return the ordinalized value instead of just the suffix?