开发者

PHP: increment counter function using words (i.e. First, Second, Third, etc.. )

I've been trying to find a function which increments a counter using words. I know its possible using numbers with suffixes (i.e. 1st, 2nd, 3rd and so on). Here is a snippet of the code i've got:

function addOrdinalNumberSuffix($num) {
    if (!in_array(($num % 100),array(11,12,13))){
        switch ($num % 10) {
            // Handle 1st, 2nd, 3rd
            case 1:  return $num.'st';
            case 2:  return $num.'nd';
            case 3:  return $num.'rd';
        }
    }
    return $num.'th';
}

Code Source

But is there a way to replicate this with words (i.e First, Second, Third, etc..)?

开发者_如何学Python

I'd expect it to be quite difficult (but not impossible) to create an infinite counter, but anything up to 20 would suffice.

Any help would be much appreciated.


There is a class from PEAR package can do that:

<?php

// include class
include("Numbers/Words.php");

// create object
$nw = new Numbers_Words();

// convert to string
echo "600 in words is " . $nw->toWords(600);

?>

Source.


Twenty isn't that much to hardcode. You'd just need an array, not a function.

$array = array('First', 'Second', 'Third', ...);

foreach ($array as $key => $value)
{
  echo "$value index is $key";
}

The more direct answer is: There isn't a built in function that does what you're looking for.


Here goes some pseudo code to perhaps lead on a hopefully good way:

input = //any number
output = string (input)
if output ends with '1' then output += 'st'
else if output ends with '2' then output += 'nd'
else if output ends with '3' then output += 'rd'
else output += 'th'


<?php

    /*****************************************************************************/

function ToOrdinal($n) {
  /* Convert a cardinal number in the range 0 - 999 to an ordinal in
     words. */

  /* The ordinal will be collected in the variable $ordinal.
   Initialize it as an empty string.*/
  $ordinal = "";

  /* Check that the number is in the permitted range. */
  if ($n >= 0 && $n <= 999)
    null;
  else{
    echo "<br />You have called the function ToOrdinal with this value: $n, but
it is not in the permitted range, from 0 to 999, inclusive.<br />";
    return;
  }
  /* Extract the units. */
  $u = $n % 10;

  /* Extract the tens. */
  $t = floor(($n / 10) % 10);

  /* Extract the hundreds. */
  $h = floor($n / 100);

  /* Determine the hundreds */
  if ($h > 0) {

    /* ToCardinalUnits() works with numbers from 0 to 9, so it's okay
       for finding the number of hundreds, which must lie within this
       range. */
    $ordinal .= ToCardinalUnits($h);
    $ordinal .= " hundred";

    /* If tens and units are zero, append "th" and quit */
    if ($t == 0 && $u == 0) {
      $ordinal .=  "th";
    } else {
      /* Otherwise put in a blank space to separate the hundreds from
     what follows. */
      $ordinal .= " ";
    }
  }

  /* Determine the tens, unless there is just one ten.  If units are 0,
     handle them separately */
  if ($t >= 2 && $u != 0) {
    switch ($t) {
    case 2:
      $ordinal .= "twenty-";
      break;
   case 3:
      $ordinal .= "thirty-";
      break;
    case 4:
      $ordinal .= "forty-";
      break;
    case 5:
      $ordinal .= "fifty-";
      break;
    case 6:
      $ordinal .= "sixty-";
      break;
    case 7:
      $ordinal .= "seventy-";
      break;
    case 8:
      $ordinal .= "eighty-";
      break;
    case 9:
      $ordinal .= "ninety-";
      break;
    }
  }
  /* Print the tens (unless there is just one ten) with units == 0 */
  if ($t >= 2 && $u == 0) {
    switch ($t) {
    case 2:
      $ordinal .= "twentieth";
      break;
    case 3:
      $ordinal .= "thirtieth";
      break;
    case 4:
      $ordinal .= "fortieth";
      break;
    case 5:
      $ordinal .= "fiftieth";
      break;
    case 6:
      $ordinal .= "sixtieth";
      break;
    case 7:
      $ordinal .= "seventieth";
      break;
    case 8:
      $ordinal .= "eightieth";
      break;
    case 9:
      $ordinal .= "ninetieth";
      break;
    }
  }


  /* Print the teens, if the tens is 1. */
  if ($t == 1) {
    switch ($u) {
    case 0:
      $ordinal .= "tenth";
      break;
    case 1:
      $ordinal .= "eleventh";
      break;
    case 2:
      $ordinal .= "twelfth";
      break;
    case 3:
      $ordinal .= "thirteenth";
      break;
    case 4:
      $ordinal .= "fourteenth";
      break;
    case 5:
      $ordinal .= "fifteenth";
      break;
    case 6:
      $ordinal .= "sixteenth";
      break;
    case 7:
      $ordinal .= "seventeenth";
      break;
    case 8:
      $ordinal .= "eighteenth";
      break;
    case 9:
      $ordinal .= "nineteenth";
      break;
    }
  }

  /* Print the units. */
  if ($t != 1) {
    switch ($u) {
    case 0:
      if ($n == 0)
    $ordinal .= "zeroth";
      break;
    case 1:
      $ordinal .= "first";
      break;
    case 2:
      $ordinal .= "second";
      break;
    case 3:
      $ordinal .= "third";
      break;
    case 4:
      $ordinal .= "fourth";
      break;
    case 5:
      $ordinal .= "fifth";
      break;
    case 6:
      $ordinal .= "sixth";
      break;
    case 7:
      $ordinal .= "seventh";
      break;
    case 8:
      $ordinal .= "eighth";
      break;
    case 9:
      $ordinal .= "ninth";
      break;
    }
  }
  return $ordinal;
}

/*****************************************************************************/


function ToCardinalUnits($n) {
  /* Convert a number in the range 0 to 9 into its word equivalent. */

  /* Make sure the number is in the permitted range. */
  if ($n >= 0 && $n <= 9)
    null;
  else
    {
      echo "<br />You have called ToCardinal() with an argument $n, but the permitted range is 0 to 9, inclusive.<br />";
    }

  switch ($n) {
  case 0:
    return "zero";
  case 1:
    return "one";
  case 2:
    return "two";
  case 3:
    return "three";
  case 4:
    return "four";
  case 5:
    return "five";
  case 6:
    return "six";
  case 7:
    return "seven";
  case 8:
    return "eight";
  case 9:
    return "nine";
  }
}



?>


Ordinals (English only), based on SIFE's answer:

include("Numbers/Words.php");

function Nth($n)
{
    $nw = new Numbers_Words();
    $s = $nw->toWords($n);
    $replacements = array(
        'one' => 'first',
        'two' => 'second',
        'three' => 'third',
        've' => 'fth',
        't' => 'th',
        'e' => 'th',
        'y' => 'ieth',
        '' => 'th',
    );
    foreach ($replacements as $from => $to)
    {
        $count = 0;
        $r = preg_replace('/' . $from . '$/', $to, $s, 1, $count);
        if ($count)
            return $r;
    }
}


Here's a link to a simple PHP function that shows how to handle this in a simple manner: http://webdeveloperblog.tiredmachine.com/php-converting-an-integer-123-to-ordinal-word-firstsecondthird/

The provided example only works into the fifties, but can easily be expanded upon to reach higher ranges.

function numToOrdinalWord($num)
{
    $first_word = array('eth','First','Second','Third','Fouth','Fifth','Sixth','Seventh','Eighth','Ninth','Tenth','Elevents','Twelfth','Thirteenth','Fourteenth','Fifteenth','Sixteenth','Seventeenth','Eighteenth','Nineteenth','Twentieth');
    $second_word =array('','','Twenty','Thirthy','Forty','Fifty');

    if($num <= 20)
        return $first_word[$num];

    $first_num = substr($num,-1,1);
    $second_num = substr($num,-2,1);

    return $string = str_replace('y-eth','ieth',$second_word[$second_num].'-'.$first_word[$first_num]);
}


A short little hack to accomplish the same result is (ab)using date() for it.

$num = 2;
echo date("jS", strtotime("January {$num}"));

// Output
"2nd"

Only works up to 31 though, and probably slower than just using an array like Parris suggested.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜