Code:function num_abbrev_str(n)
{
return n + (( Math.floor(n/10) == 1) ? "th" : ["th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"][n%10]);
}
Printable View
Code:function num_abbrev_str(n)
{
return n + (( Math.floor(n/10) == 1) ? "th" : ["th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"][n%10]);
}
Whoa. :cool:
That works for dates, doesn't work for 113
Yeh I wasn't thinking above dates.
I think liorean has the best solution
function num_abbrev_str(n)
{
i = n % 100;
return n + (( Math.floor(i/10) == 1) ? "th" : ["th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"][i%10]);
}
jsWalter
Hi jsWalter,
You beat me to it. I was going to do it in one step
but it is essentially the same thing.Code:function num_abbrev_str(n)
{
return n + (( Math.floor((n%100)/10) == 1) ? "th" : ["th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"][n%10]);
}
I just noticed that liorean is assuming that in boolean expressions true==1
( this % 100 - nModTen != 10 )
Should evaluate to 0 or 1 and then multiply it by a value.
Hmm sneaky :)
(but maybe a little dangerous)
Yah, I know it's sneaky. It's one of the tricks I thought of when I read through the JavaScript and ECMAScript specs recently, and this is the first time I've got to put it to use. Try it: <javascript:alert(Number(Boolean(2)));void(0);>
Oh, just wondering - what might be fastest:With one scope jump, one property lookup, one function call, one remainder, one division and one comparison, orCode:(( Math.floor((n%100)/10) == 1)
With one remainder, one subtraction, one comparison, one autocasting, and one multiplication.Code:( this % 100 - nModTen != 10 ) * nModeTen
I believe your code would win out, in those cases. (The access part (scope jump and property lookup) should be fast compared to my math, and the function call and the autocast should both be almost unnoticable) However, my single comparison should make my code faster in the cases of 'th', when I won't have to perform all those numerical operations. So, how would they compare for many numbers, performance wise?
This is the kind of discussion that totally rules. :)
Oh, having a look at your code, this change saves space, but I think it makes for slightly worse performance. I think it's cleaner looking, though:
Code:function num_abbrev_str(n)
{
return n + (( Math.floor((n%100)/10) == 1) ? "th" : ([, "st", "nd", "rd", ,,,,,][n%10]) || 'th');
}
I like the boolean trick and I like the idea of only having 4 strings in the array
In this 60% of the time theCode:function num_abbrev_str(n)
{
return n + ["th","st","nd","rd"][!(n%10>3||Math.floor(n%100/10)==1)*n%10];
}
(n%10>3)
will be true so the
Math.floor(n%100/10)==1
will only be executed for 40% of the numbers.
Invert the boolean and do the multiply
NOTE: I have utilised operator precedence to reduce char count.
Here is a version with parentheses to show precedence
PHP Code:
function num_abbrev_str(n)
{
return n + ["th","st","nd","rd"][(!( ((n%10) >3) || (Math.floor(n%100/10)==1)) ) * (n%10)];
}
I personally think that's a work of art... :D
I personnaly thought I knew something about javascript. I now think I know nothing !
I know it's PHP but I thought somone was bound to know the JavaScript syntax for the regexp check.
<?php
$days = range(1, 31);
foreach($days as $day)
{
if(ereg("(^[23]?1$)", $day))
{
$suff = "st";
}
elseif(ereg("(^2?2$)", $day))
{
$suff = "nd";
}
elseif(ereg("(^2?3$)", $day))
{
$suff = "rd";
}
else
{
$suff = "th";
}
echo $day . $suff . "<br />";
}
?>
That really was an old thread you dug up...
This problem is much less complex when handling it as numbers compared to handling it as strings. Math is generally easier to work with than string comparisons, especially when it's a numerical problem.
What about this to test the values in the easiest to follow way:
switch (aNum) {
case 1:
case 21:
case 31:
suffix = 'st';
break;
case 2:
case 22:
suffix = 'nd';
break;
case 3:
case 23:
suffix = 'rd';
break;
default:
suffix = 'th';
}
I think that this is an interesting discussion. I see that there are a number of solutions for this problem. I think, though, that it is always important to generalize when developing script code that could be used in a number of situations. That said, I wrote a short function which will do the trick for any positive or negative integer. The code can be found at http://gotochriswest.com/development...OrdinalFor.php. Alternatively, you can also find it below:
Code:Number.getOrdinalFor = function(intNum, includeNumber)
{
return (includeNumber ? intNum : "") + (((intNum = Math.abs(intNum) % 100)
% 10 == 1 && intNum != 11) ? "st" : (intNum % 10 == 2 && intNum != 12)
? "nd" : (intNum % 10 == 3 && intNum != 13) ? "rd" : "th");
};