# function to append “a” or “an” to the front of a number as appropriate

Input: any integer

Output: that integer in number format (commas) with a leading a or an as appropriate with the rules of English

After a bit of groping around I hacked out the following PHP function, and am looking for any advice on code structure and optimization. Thank you!

function prefixAAnToNumber($num) {$prefixAn = array(8, 11, 18, '8', '11', '18');
$verAn = 'an ' . number_format($num);
$verA = 'a ' . number_format($num);

if (in_array($num,$prefixAn)) {
return $verAn; } else if (strlen($num) > 1) {
$numComma = number_format($num);
if (substr($numComma,0,1) == '8') { return$verAn;
} else if (in_array(substr($numComma,0,2),$prefixAn) && substr($numComma,2,1) == ',') { return$verAn;
} else {
return $verA; } } else { return$verA;
}
}


Example usage:

$num = 11; for ($i = 0; $i < 10; ++$i) {
echo '<p>'.$num.' -> "'; echo prefixAAnToNumber($num);
echo ' kg shipment"</p>';
$num =$num * 10;
}


Output:

11 -> "an 11 kg shipment"

110 -> "a 110 kg shipment"

1100 -> "a 1,100 kg shipment"

11000 -> "an 11,000 kg shipment"

110000 -> "a 110,000 kg shipment"

1100000 -> "a 1,100,000 kg shipment"

11000000 -> "an 11,000,000 kg shipment"

110000000 -> "a 110,000,000 kg shipment"

1100000000 -> "a 1,100,000,000 kg shipment"

11000000000 -> "an 11,000,000,000 kg shipment"

• Not a function, but a component made for such jobs: php.net/manual/en/class.numberformatter.php – hakre Jan 6 '12 at 16:31
• "1,100" can go either way depending on whether you pronounce it "thousand one hundred" or "eleven hundred". I'd opt for the second, so my expected function results are different from yours. – hvd Jan 8 '12 at 21:06
• @hvd - you're correct, of course. I chose to interpret it as "one thousand one hundred" to simplify my code, even though I'd read it as "eleven hundred" in casual speech. – Drew Jan 9 '12 at 1:32
• @hakre - thanks for the link. I assumed something existed already either in the core function set or on phpclasses.org, but I wanted to write the function as a learning exercise. I'm glad I did, the answers reveal that my formatting and logic layout still needs a lot of work! – Drew Jan 9 '12 at 1:33

Rather than having many return statements I would keep the logic that determines whether it should be 'a' or 'an' together. I think it is actually easier to understand reading the ANDs and ORs than spread out if and else statements.

I prefer not to create temporary variables that are not used for anything - so I wouldn't create $verA and $verAn. I do however create a variable for $numComma. By having this we avoid calling number_format more than is necessary. This is how it looks my way: function prefixAAnToNumber($num)
{
$prefixAn = array(8, 11, 18, '8', '11', '18');$numComma = number_format($num); if (in_array($num, $prefixAn) || (strlen($num) > 1 &&
(substr($numComma, 0, 1) == '8' || (in_array(substr($numComma, 0, 2), $prefixAn) && substr($numComma, 2, 1) == ','))))
{
return 'an ' . $numComma; } return 'a ' .$numComma;
}


I don't know if you have noticed but all numbers that start with an an have the numbers in the array before the comma.

So what you can do:

function prefixAAnToNumber($num) {$prefixAn = array(8, 11, 18, '8', '11', '18');
$number = number_format($num);
$numberSplit = explode(',',$number);
$a = 'a'; if(in_array($numberSplit[0], $prefixAn) || substr($number,0,1) == '8')
$a .= 'n'; return "$a \$number";
}


Output:

11 -> "an 11 kg shipment"
110 -> "a 110 kg shipment"
1100 -> "a 1,100 kg shipment"
11000 -> "an 11,000 kg shipment"
110000 -> "a 110,000 kg shipment"
1100000 -> "a 1,100,000 kg shipment"
11000000 -> "an 11,000,000 kg shipment"
110000000 -> "a 110,000,000 kg shipment"
1100000000 -> "a 1,100,000,000 kg shipment"
11000000000 -> "an 11,000,000,000 kg shipment"