Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@furf
Forked from 140bytes/LICENSE.txt
Created May 23, 2011 02:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save furf/986113 to your computer and use it in GitHub Desktop.
Save furf/986113 to your computer and use it in GitHub Desktop.
Return the ordinal suffix for a number.

140byt.es

A tweet-sized, fork-to-play, community-curated collection of JavaScript.

How to play

  1. Click the Fork button above to fork this gist.
  2. Modify all the files to according to the rules below.
  3. Save your entry and tweet it up!

Rules

All entries must exist in an index.js file, whose contents are

  1. a valid Javascript function expression, that
  2. optionally self-executes,
  3. contains no more than 140 bytes, and
  4. does not pollute global scope.

All entries must also be licensed under the MIT license.

For more information

The 140byt.es site hasn't launched yet, but for now follow @140bytes on Twitter.

To learn about byte-saving hacks for your own code, or to contribute what you've learned, head to the wiki.

140byt.es is brought to you by Jed Schmidt. It was inspired by work from Thomas Fuchs and Dustin Diaz.

function(){
/* Rules:
(1) anonymous function // make sure
(2) may be self-executing // to annotate
(3) <=140 bytes // your code
(4) no globals // so everyone
(5) MIT license // can learn
(6) have a good time! // from it!
*/}
function(){/*Rules: (1) anonymous function (2) may be self-executing (3) <=140 bytes (4) no globals (5) MIT license (6) have a good time!*/}
Copyright (c) 2011 YOUR_NAME_HERE, YOUR_URL_HERE
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.
{
// [REQUIRED] A name for your library.
// This must match /^[a-z_]\w*$/i
"name": "140bytes",
// [OPTIONAL] A description of your library, phrased as a verb predicate.
// The gist description is used by default.
"description": "Explain the 140byt.es rules.",
// [OPTIONAL] Up to 5 keywords used for indexing.
"keywords": [
"140bytes",
"master",
"rules"
]
}
@jed
Copy link

jed commented May 23, 2011

great work! just out of curiosity, why no return the ordinalized value instead of just the suffix?

@furf
Copy link
Author

furf commented May 23, 2011

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. :)

@jed
Copy link

jed commented May 23, 2011

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('')

@furf
Copy link
Author

furf commented May 23, 2011

Interesting. I would prefer your syntax in the case where the value being passed is not stored.

32+ordinal(32) // looks a little silly

But 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 concatenation

PS--I'm really digging the 140bytes project. Lots of good reads. Cheers!

@tsaniel
Copy link

tsaniel commented Oct 23, 2011

My version.

function(a){return[,"st","nd","rd"][/1?.$/.exec(a)]||"th"}

@furf
Copy link
Author

furf commented Oct 23, 2011

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!

@lsauer
Copy link

lsauer commented Oct 24, 2011

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
};

@furf
Copy link
Author

furf commented Oct 25, 2011

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.

@tsaniel
Copy link

tsaniel commented Jan 26, 2012

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'}

@furf
Copy link
Author

furf commented Mar 22, 2012

21th? 22th? 23th?

@furf
Copy link
Author

furf commented Mar 22, 2012

11st? 12nd? 13rd? Keep trying! :)

@furf
Copy link
Author

furf commented Mar 22, 2012

i like tsaniels bitwise the best for all practical purposes. non-negative integers are typically all you'll need.

@williammalo
Copy link

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.

@tsaniel
Copy link

tsaniel commented Mar 23, 2012

@furf: Did you mean you find a bug? But it just works fine with me.

@williammalo
Copy link

@tsaniel no, he found a bug in my code, I deleted the original post. Your function is perfect.

@tsaniel
Copy link

tsaniel commented Mar 23, 2012

Oh I see.
Shave another byte off by the way:

function(a){return[,'st','nd','rd'][a/10%10^1&&a%10]||'th'}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment