Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Regular Coder
    Join Date
    Oct 2009
    Posts
    190
    Thanks
    12
    Thanked 2 Times in 2 Posts

    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.

  • #2
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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

  • #3
    New Coder
    Join Date
    Jan 2010
    Location
    UT
    Posts
    35
    Thanks
    1
    Thanked 3 Times in 3 Posts
    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)

  • #4
    Regular Coder
    Join Date
    Oct 2009
    Posts
    190
    Thanks
    12
    Thanked 2 Times in 2 Posts
    *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.

  • #5
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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
    and everything ended with "th".
    and what you expect to be instead th?

    best regards

  • #6
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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,

  • #7
    Regular Coder
    Join Date
    Oct 2009
    Posts
    190
    Thanks
    12
    Thanked 2 Times in 2 Posts
    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.

  • #8
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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

  • #9
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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

  • #10
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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

  • #11
    Senior Coder kbluhm's Avatar
    Join Date
    Apr 2007
    Location
    Philadelphia, PA, USA
    Posts
    1,509
    Thanks
    3
    Thanked 258 Times in 254 Posts
    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;


  • #12
    Regular Coder
    Join Date
    Oct 2009
    Posts
    190
    Thanks
    12
    Thanked 2 Times in 2 Posts
    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?

  • #13
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    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).
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    oesxyl (01-22-2010)

  • #14
    Master Coder
    Join Date
    Dec 2007
    Posts
    6,682
    Thanks
    436
    Thanked 890 Times in 879 Posts
    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

  • #15
    New Coder
    Join Date
    Oct 2011
    Posts
    12
    Thanks
    0
    Thanked 1 Time in 1 Post
    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?


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •