Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Counting numbers in english 10

Status
Not open for further replies.

BabyJeffy

Programmer
Joined
Sep 10, 2003
Messages
4,189
Location
GB
The way we count numbers in English appears quite strange (I am sure) to those who don't speak it natively. When we refer to dates we often add "st", "rd", "nd" or "th" to the end of any numbers. Example: 10th February, 23rd June

I remember one solution I used for solving this "problem" early in my career. There can be up to 31 days in a month, so I created an array and populated it with the correct endings:
Code:
var numberWords = ['X','st','nd','rd','th','th','th','th','th','th','th','th','th','th',
'th','th','th','th','th','th','th','st','nd','rd','th','th','th','th','th','th','th','st'];
And I would then get the correct ending by calling the index of the array with the number directly:
Code:
function getNumberExt(theNumber) {
  return (theNumber+numberWords[theNumber]);
}
alert(getNumberExt(23)); // alerts 23rd
My example contains no attempt at error checking (and this is certainly not appropriate for production quality code).

I've used much the same code server-side as well as client-side and it's done the job well. I am interested in how others have achieved a similar result.

Does anyone have any significantly different mechanisms to do this? Want to share?

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]

What is Javascript? faq216-6094
 
...and then adapting it to something USEFUL :)

Code:
<script type="text/javascript"><!--
function orderNum(theNumber)
{
    var s = theNumber%10;
    var t = theNumber%100;
    var y = (t<20&&t>10);
    var o;
    o = theNumber + ((s==1&&!y)?"st":((s==2&&!y)?"nd":((s==3&&!y)?"rd":"th")));
    return o;
}//end function
//--></script>

Nice work, Cory! I'd give you a star, but you know how I feel about you and stars!

--Dave


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O Time, Strength, Cash, and Patience! [infinity]
 
OK, gotta congrat you on that one Cory.

But, I could not give up on my own little script so, based on what manarth was saying I modified it to this:

Code:
function getNumberExt(theNumber) {
  var endnum = (theNumber.charAt(theNumber.length-2) == '1')?'th':theNumber.charAt(theNumber.length-1);
  switch (endnum) {
    case '1': var endtag = "st"; break;
    case '2': var endtag = "nd"; break;
    case '3': var endtag = "rd"; break;
    default: var endtag = 'th';
  }
  return (theNumber+endtag);
}

Or slightly shorter:
Code:
function getNumberExt(theNumber) {
  var endnum = (theNumber.charAt(theNumber.length-2) == '1')?'th':theNumber.charAt(theNumber.length-1);
  switch (endnum) {
    case '1': return (theNumber + 'st');
    case '2': return (theNumber + 'nd');
    case '3': return (theNumber + 'rd');
    default: return (theNumber + 'th');
  }
}

It's a bit easier on my head when I try to read it. :)


Paranoid? ME?? WHO WANTS TO KNOW????
 
actually I go with LookingForInfo's script, with a few slight change:
Code:
	function numEnding(n) {
	  t = ((n%100>10) && (n%100<20));
	  u = n%10;
	  a = (!t&&u==1)?"st":(!t&&u==2)?"nd":(!t&&u==3)?"rd":"th";
	  return(a);
	}
one less variable, one less line of code, one extra operation...Save The Bandwidth :)

<marc>
New to Tek-Tips? Get better answers - faq581-3339
 
Why not take it a step further and change:
Code:
a = (!t&&u==1)?"st":(!t&&u==2)?"nd":(!t&&u==3)?"rd":"th";
return(a);

to:
Code:
return((!t&&u==1)?"st":(!t&&u==2)?"nd":(!t&&u==3)?"rd":"th");

--Dave


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O Time, Strength, Cash, and Patience! [infinity]
 
obviously, for the sake of argument, this can be done in one line. it's a question of whether you want extra calculations and looking cool with one line of code, or using a couple fewer calculations and having three lines of code.

*cLFlaVA
----------------------------
[tt]I already made like infinity of those at scout camp...[/tt]
beware of active imagination: [URL unfurl="true"]http://www.coryarthus.com/[/url]

BillyRayPreachersSonIsTheLeetestHax0rDude
[banghead]
 
LookingForInfo said:
Why not take it a step further and change:
Code:
a = (!t&&u==1)?"st":(!t&&u==2)?"nd":(!t&&u==3)?"rd":"th";
return(a);

to:
Code:
return((!t&&u==1)?"st":(!t&&u==2)?"nd":(!t&&u==3)?"rd":"th");
habit :)

i tend to throw things into a variable before returning the variable. i think i find it easier to read; i'm not certain, but i'm not so fussed i want to change.

so, habit!

<marc>
New to Tek-Tips? Get better answers - faq581-3339
 
Buzz kill. :p


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O Time, Strength, Cash, and Patience! [infinity]
 
I'm not sure but this should also work:
Code:
function orderNum( n )
{		return( n+"thstndrd".substr(2*(n%10<3 && (n%100-n%10!=10)) * n%10, 2) );	
}

------
"There's a man... He's bald and wears a short-sleeved shirt, and somehow he's very important to me. I think his name is Homer."
(Jack O'Neill, Stargate)
[banghead]
 
Aww cr@p... here comes hotfix: replace < with <= [blush].

------
"There's a man... He's bald and wears a short-sleeved shirt, and somehow he's very important to me. I think his name is Homer."
(Jack O'Neill, Stargate)
[banghead]
 
That's something, vongrunt!

Got another one, BabyJeffy?

To those of you who are celebrating this weekend: Happy Thanksgiving!

--Dave


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O Time, Strength, Cash, and Patience! [infinity]
 
Code:
function numEnding3(n) {return (!((n%100>10) && (n%100<20))&&((n%10)==1))?"st":(!((n%100>10) && (n%100<20))&&((n%10)==2))?"nd":(!((n%100>10) && (n%100<20))&&((n%10)==3))?"rd":"th";}

Paranoid? ME?? WHO WANTS TO KNOW????
 
OK, if we want to go much shorter than vongrunt's code I think we need to get the function added into the javascript standard.


Paranoid? ME?? WHO WANTS TO KNOW????
 
Code:
[b]#!/usr/bin/perl[/b]

$suffix{1} = 'st';
$suffix{2} = 'nd';
$suffix{3} = 'rd';

foreach (1..100) {
  print "$_" . $suffix{substr($_, -1, 1)};
  print "th" if !defined $suffix{substr($_, -1, 1)} || ($_ <= 11 && $_ >= 13);
  print "\n";
}

Kind Regards
Duncan
 
sorry... wrong forum!

Kind Regards
Duncan
 
duncdude said:
sorry... wrong forum
That's ok - in fact it encourages me even more!

Anyone able (willing) to take this into seriously obscure territory... how about dragging out some of those "old skool" (I'm talking pre-80's) languages?

I know we can obfuscate these - but if you do... craft it...

Example:
Code:
while (hell != frozen) code(javascript);

I just wish I could remember ProLog well enough to contribute [smile]

Happy Thanksgiving over the pond!

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]

What is Javascript? faq216-6094
 
By the way... excellent stuff everyone! It's refreshing to see something trivial approached in so many different ways.

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]

What is Javascript? faq216-6094
 
Another way for the big melting pot of ways:

Code:
<html>
<head>
	<script type="text/javascript">
	<!--
		function getSuffix(num) {
			return(['th', 'st', 'nd', 'rd'][((i = num % 10) > 3 || (num > 10 && num < 14)) ? 0 : i]);
		}

		var s = '';
		for (var loop=1; loop<40; loop++) {
			s += loop + getSuffix(loop) + '\n';
		}
		alert(s);
	//-->
	</script>
</head>
<body></body>
</html>

Quite enjoyed that. We should do it more often!

Dan

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
This code uses a silly bitshifty bit to choose the suffix and then becomes even more obscure by picking the letters for the suffix out of the word "nerdshift" !

Code:
function NerdShift(nerd)
{
  var shift=nerd-(nerd.substring(0,nerd.length-2)+"00");

  if(shift>>>4==0&&shift>>>2>0) 
    shift="85";
  else 
  {
    shift=3^(shift-((shift>>>2)<<2));
    shift=(0==shift?"23":1==shift?"03":2==shift?"48":"85");
  }

  shift="nerdshift".charAt(shift.charAt(0))
       +"nerdshift".charAt(shift.charAt(1));

  return(nerd+shift);   
}
 
NerdShift isn't quite right:
...
16th
17st
18nd
19rd
...


-jeff
try { succeed(); } catch(E) { tryAgain(); } finally { rtfm(); }
i like your sleeves...they're real big
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top