1
\$\begingroup\$

I'm looking for feedback to improve this function. The purpose is to pass a noun and append the appropriate indefinite article ("a" or "an").

A known issue with this code is that it doesn't address words with a vowel sound but a consonant first letter, such as "honor" or "hour". I cannot include 'h' in the list of vowels, though; words like "home" or "horror" have a harder 'h' sound and use the article "a".

function aan ($string) {
    return (
        in_array(
            strtolower(substr($string, 0, 1)),
            array('a','e','i','o','u')
        ) ? 'an' : 'a'
    ).' '.$string;
}

Current output:

print 'Become '.aan('All-access').' member'; // Become an All-access member
print 'Become '.aan('Basic').' member'; // Become a Basic member
print 'It has been '.aan('interesting').' experience'; // It has been an interesting experience
\$\endgroup\$
3
  • 3
    \$\begingroup\$ The logic is flawed. In English, you can't base a/an on written form. You have to base it on word pronuncation. If you don't have the pronunciation for every word, you will never make it work. Common examples - "a unit" vs "an uncle" \$\endgroup\$
    – Sulthan
    Commented Jan 8, 2013 at 16:23
  • 2
    \$\begingroup\$ @Sulthan ... as I mention in the second paragraph. \$\endgroup\$
    – Chris
    Commented Mar 4, 2013 at 15:05
  • 3
    \$\begingroup\$ it is unclear what kind of feedback you are looking for to improve this function. performance, readability, speed, efficiency.... \$\endgroup\$
    – Malachi
    Commented Dec 21, 2013 at 3:56

2 Answers 2

1
\$\begingroup\$

It would be simpler to use stristr() and $string[0].

function indefinite_article_heuristic($string) {
    return (stristr('aeiou', $string[0]) ? 'an ' : 'a ') . $string;
}

stripos() would probably be slightly more efficient, but you would have to do

function indefinite_article_heuristic($string) {
    return (FALSE === stripos('aeiou', $string[0]) ? 'a ' : 'an ') . $string;
}

which looks icky.

\$\endgroup\$
2
\$\begingroup\$

A tiny improvement to reduce a string concatenation:

function aan ($string) {
    return (
        in_array(
            strtolower(substr($string, 0, 1)),
            array('a','e','i','o','u')
        ) ? 'an ' : 'a '
    ).$string;
}

In order to help get your logic for more cases (ie, your Honor or Hour examples), you may wish to visit the English StackExchange to get help in figuring that logic out. Then you can code that as well.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.