Go Back   CodingForums.com > :: Server side development > PHP > Post a PHP snippet

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-17-2010, 10:44 PM   PM User | #1
tspek
Regular Coder

 
Join Date: Oct 2009
Posts: 190
Thanks: 12
Thanked 2 Times in 2 Posts
tspek is an unknown quantity at this point
Add proper ending to number (st, nd, rd, th)

I'm pretty sure (though it's very possible I'm wrong) that PHP doesn't have anything built in to do this outside of dates and I searched the internet and couldn't find anything worth a darn via google.

PHP Code:
#Adds st nd rd th to appropriate numbers
function number_ending ($number)
{
    
// Get the last character of a string.
    
$str $number;
    
$string $str[strlen($str)-1];
    
$j 0;
    
    if (
$string == 1)
    {
        
$ending "st";
        ++
$j;
    }
    else if (
$string == 2)
    {
        
$ending "nd";
        ++
$j;
    }
    else if (
$string == 3)
    {
        
$ending "rd";
        ++
$j;
    }
     
    else if (
$string == 11)
           {
                
$ending "th";
               ++
$j;
           }

    else
    {
        
$ending "th";
        ++
$j;
    }
    
    if (
$j == 1)
    {
        
$number "$number"."$ending";
        return 
$number;
    }


Last edited by tspek; 01-17-2010 at 11:14 PM..
tspek is offline   Reply With Quote
Old 01-17-2010, 10:50 PM   PM User | #2
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
PHP Code:
function number_ending ($number){
   
$suff = array("","st","nd","rd","th");
   
$index intval($number);
   if(
$index 4){
      
$index 4;
   }elseif(
$index 1){
      
$index 0;
   }
   return (
$number $suff[$index]);

best regards
oesxyl is offline   Reply With Quote
Old 01-17-2010, 11:01 PM   PM User | #3
Zoic
New Coder

 
Join Date: Jan 2010
Location: UT
Posts: 35
Thanks: 1
Thanked 3 Times in 3 Posts
Zoic is an unknown quantity at this point
I tried oesxyl's function and it stopped working at 21 and everything ended with "th".

I found the following code on http://www.talkphp.com/tips-tricks/2...ers-dates.html and it worked like a charm.

PHP Code:
<?php
function show_ordinal($num) {
    
// first convert to string if needed
    
$the_num = (string) $num;
    
// now we grab the last digit of the number
    
$last_digit substr($the_num, -11);
    
// if the string is more than 2 chars long, we get
    // the second to last character to evaluate
    
if (strlen($the_num)>1) {
        
$next_to_last substr($the_num, -21);
    } else {
        
$next_to_last "";
    }
    
// now iterate through possibilities in a switch
    
switch($last_digit) {
        case 
"1":
            
// testing the second from last digit here
            
switch($next_to_last) {
                case 
"1":
                    
$the_num.="th";
                    break;
                default:
                    
$the_num.="st";
            }
            break;
        case 
"2":
            
// testing the second from last digit here
            
switch($next_to_last) {
                case 
"1":
                    
$the_num.="th";
                    break;
                default:
                    
$the_num.="nd";
            }
            break;
        
// if last digit is a 3
        
case "3":
            
// testing the second from last digit here
            
switch($next_to_last) {
                case 
"1":
                    
$the_num.="th";
                    break;
                default:
                    
$the_num.="rd";
            }
            break;
        
// for all the other numbers we use "th"
        
default:
            
$the_num.="th";
    }

    
// finally, return our string with it's new suffix
    
return $the_num;
}
?>
(I searched for php number suffix in google)
Zoic is offline   Reply With Quote
Old 01-17-2010, 11:09 PM   PM User | #4
tspek
Regular Coder

 
Join Date: Oct 2009
Posts: 190
Thanks: 12
Thanked 2 Times in 2 Posts
tspek is an unknown quantity at this point
*Edit*

I didn't see the other response. Assuming his doesn't work, mine would be the shortest yet, does that make a difference in terms of speed?

I also just realized that 11 would come out 11st...thus requiring another another if statement...

Last edited by tspek; 01-17-2010 at 11:13 PM..
tspek is offline   Reply With Quote
Old 01-17-2010, 11:12 PM   PM User | #5
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
Quote:
Originally Posted by Zoic View Post
I tried oesxyl's function and it stopped working at 21
it work for me:

PHP Code:
<?php

function number_ending($number){
  
$suff = array("","st","nd","rd","th");
  
$index intval($number);
  if(
$index 4){
    
$index 4;
  }elseif(
$index 1){
    
$index 0;
  }
  return (
$number $suff[$index]);
}

for(
$i=-1;$i<100;$i++){
  print 
number_ending($i) . "\n";
}

?>
Code:
-1
0
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11th
12th
13th
14th
15th
16th
17th
18th
19th
20th
21th
22th
23th
24th
25th
26th
27th
28th
29th
30th
31th
32th
33th
34th
35th
36th
37th
38th
39th
40th
41th
42th
43th
44th
45th
46th
47th
48th
49th
50th
51th
52th
53th
54th
55th
56th
57th
58th
59th
60th
61th
62th
63th
64th
65th
66th
67th
68th
69th
70th
71th
72th
73th
74th
75th
76th
77th
78th
79th
80th
81th
82th
83th
84th
85th
86th
87th
88th
89th
90th
91th
92th
93th
94th
95th
96th
97th
98th
99th
Quote:
and everything ended with "th".
and what you expect to be instead th?

best regards
oesxyl is offline   Reply With Quote
Old 01-17-2010, 11:15 PM   PM User | #6
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
Quote:
Originally Posted by tspek View Post
*Edit*

I didn't see the other response. Assuming his doesn't work, mine would be the shortest yet, does that make a difference in terms of speed?

I also just realized that 11 would come out 11st...thus requiring another another if statement...
I mess this too,
oesxyl is offline   Reply With Quote
Old 01-17-2010, 11:16 PM   PM User | #7
tspek
Regular Coder

 
Join Date: Oct 2009
Posts: 190
Thanks: 12
Thanked 2 Times in 2 Posts
tspek is an unknown quantity at this point
Quote:
Originally Posted by oesxyl View Post
it work for me:

[php]
and what you expect to be instead th?

best regards

33 would be 33rd not 33th.
tspek is offline   Reply With Quote
Old 01-17-2010, 11:17 PM   PM User | #8
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
just fix the problem:
PHP Code:
function number_ending ($number){
   
$suff = array("","st","nd","rd","th");
   
$index intval($number) % 10;
   if(
$index 4){
      
$index 4;
   }elseif(
$index 1){
      
$index 0;
   }
   return (
$number $suff[$index]);

best regards
oesxyl is offline   Reply With Quote
Old 01-17-2010, 11:24 PM   PM User | #9
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
Quote:
Originally Posted by tspek View Post
33 would be 33rd not 33th.
same like what you post in #1, I also mess it and everything after 3 ends in th.
I fix this in #8. I don't know which is faster, mine is obvious shorter.

best regards
oesxyl is offline   Reply With Quote
Old 01-18-2010, 12:22 AM   PM User | #10
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
seems that previous was incorrect, see 11st, 12nd, 13rd vs. 11th, 12th, 13th:
Fixed:
PHP Code:
<?php
/*
 * seeAlso:
 *    http://en.wikipedia.org/wiki/Names_of_numbers_in_English#Ordinal_numbers
 *
 * 0, 1st, 2nd, 3rd, 4th, ...
 * 10th, 11th, 12th, 23th, ...
 * 20th, 21st, 22nd, 33rd, 34th
 */
function number_ending($number){
  
$n intval($number);
  
$suff = array("","st","nd","rd","th");
  
$index $n 10// index ok for 0-9, i1-i9 (i > 2)
  
if($index || ($index == && $n 0) || ($n 10 && $n 20)){
    
$index 4;
  }elseif(
$index 1){
    
$index 0;
  }
  return (
$number $suff[$index]);
}

// test:
for($i=-1;$i<100;$i++){
  print 
number_ending($i) . "\n";
}

?>
best regards
oesxyl is offline   Reply With Quote
Old 01-18-2010, 12:33 AM   PM User | #11
kbluhm
Senior Coder

 
kbluhm's Avatar
 
Join Date: Apr 2007
Location: Philadelphia, PA, USA
Posts: 1,502
Thanks: 2
Thanked 258 Times in 254 Posts
kbluhm will become famous soon enough
PHP Code:
function ordinalize$number )
{
    if ( 
is_numeric$number ) && <> $number )
    {
        if ( 
in_array$number 100range1113 ) ) )
        {
            return 
$number 'th';
        }
        switch ( 
$number 10 )
        {
            case 
1:  return $number 'st';
            case 
2:  return $number 'nd';
            case 
3:  return $number 'rd';
            default: return 
$number 'th';
        }
    }
    return 
$number;

__________________
ZCE
kbluhm is offline   Reply With Quote
Old 01-22-2010, 03:32 PM   PM User | #12
tspek
Regular Coder

 
Join Date: Oct 2009
Posts: 190
Thanks: 12
Thanked 2 Times in 2 Posts
tspek is an unknown quantity at this point
I'm very new to PHP and programming in general. It's becoming increasingly clearer that there is more than one way to do just about anything and ultimately it comes down to using the most efficient method available.

The question then is how we know which way is the most efficient.

Here we have 3 functions that all do the same thing different ways, which one works the best though?
tspek is offline   Reply With Quote
Old 01-22-2010, 04:16 PM   PM User | #13
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,653
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Thats trickier to answer. When it comes to algorithms, most of them can be calculated by an order of magnitude. Since these all have an O(1) magnitude, they are all technically as efficient from a magnitude view. Magnitude really only cares about the 'big' picture as a whole.

So, look at other factors. Datatypes are my primary concern. If you treat you're number as a string, you will waste time and resource, but looking at the last digit itself is a matter of a char lookup. So, should the number be interpreted as a string, any string > 4 characters in length has exceeded the memory size required for any number storable as an integer (and this will increase in PHP6 which is going to native unicode).

kbluhm and oesxyl have both ensured that they are working with numbers. Oesyxl's approach is slightly more efficient, but will not tell you if its actually a number (and therefore becomes untrappable). It doesn't care if you give it a string, if you do it will cast it to a number. I believe that the is_* functions are slightly less efficient than direct casting. The benifit is you can toss and trap errors associated with this approach.

Though the codes are negligable, efficiency wise I expect that oesxyl's will be slightly faster in execution time; however, like I mentioned there is little that can be done to trigger / throw and trap any errors from it since it technically cannot have any errors with the explicit casting. Oesxyl's appears to also waste a little more memory than kbluhm's method since it declares two local variables (since the third is a write-on-copy context).
Weight on weight, I'll bet if I tested these to benchmark on precision to 1000, they would come up identical. At 100000, I'd suspect to see a 5 - 8 variance, which is incredibly tiny.

Also, one more factor is readability. Efficiency is IMO tossable for readability in languages like PHP. We're not doing embedded microprocessing, so memory and cpu are not really an issue nowadays. You can certainly take a more readable approach so you can understand later what you've done without needing to walk through it step by step (from the above, kbluhm's is more readable than oesxyl's).
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
oesxyl (01-22-2010)
Old 01-22-2010, 04:18 PM   PM User | #14
oesxyl
Master Coder


 
Join Date: Dec 2007
Posts: 6,682
Thanks: 436
Thanked 890 Times in 879 Posts
oesxyl is a jewel in the roughoesxyl is a jewel in the roughoesxyl is a jewel in the rough
Quote:
Originally Posted by tspek View Post
I'm very new to PHP and programming in general. It's becoming increasingly clearer that there is more than one way to do just about anything and ultimately it comes down to using the most efficient method available.

The question then is how we know which way is the most efficient.

Here we have 3 functions that all do the same thing different ways, which one works the best though?
depend of what do you mean by "works the best".

best regards
oesxyl is offline   Reply With Quote
Old 10-21-2011, 05:44 PM   PM User | #15
Cjwinnit
New Coder

 
Join Date: Oct 2011
Posts: 12
Thanks: 0
Thanked 1 Time in 1 Post
Cjwinnit is an unknown quantity at this point
My thoughts:
PHP Code:
function ordinal $ordnum ) {
  
$ordinalsuffixes = array("th","st","nd","rd");
  for(
$i=1;$i<=3;$i++) { if(($ordnum 10 == $i) && ($ordnum 100 != 10+$i )) return $ordinalsuffixes[$i]; }
return 
$ordinalsuffixes[0] ;    } 
If you wanted an error-check you could insert this as the first line in the func.:
PHP Code:
  if(!((gettype($ordnum) == "integer") && ($ordnum 0))) return false
I think I win for the shortest code. Cookie?
Cjwinnit is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 01:48 PM.


Advertisement
Log in to turn off these ads.