Question

I have this function which categorizes the age of a user in a certain age group:

private function calculateAgeGroup($age)
{
    if (!$age) {
        return null;
    }

    if ($age <= 25) {
        return '0-25';
    }

    if ($age <= 30) {
        return '26-30';
    }

    if ($age <= 35) {
        return '31-35';
    }

    if ($age <= 40) {
        return '36-40';
    }

    if ($age <= 45) {
        return '41-45';
    }

    if ($age <= 50) {
        return '46-50';
    }

    if ($age <= 60) {
        return '51-60';
    }

    return '61-';
}

Is there a way to simplify (meaning: less verbose, less if statements) this? My first thought was about using modulo, but I dismissed that very fast as it just doesn't make sense to use modulo here.

Second option would be something like floor($age/10)*10 . "-" . ceil($age/10)*10 but that also doesn't work in all cases.

The last option which came to my mind would be using a series of () ? : statements which would make for shorter but NOT more readable code. Also not so good.

Anyone has any good idea how to simplify this? Suggestions appreciated.

Était-ce utile?

La solution

Try this code:

function calculateAgeGroup($age) {
    switch($age) {
    case $age <= 25:
        return '0-25';
        break;
    case $age > 50 && $age <= 60:
        return '51-60';
        break;
    case $age > 60:
        return '61-';
        break;
    default:
        return (floor(($age-1)/5)*5+1) . "-" . ceil($age/5)*5;
    }
}

Autres conseils

As a base you can use the following code for your increments:

private function calculateAgeGroup($age)
{
    if (!$age) return null;
    for ($i=25; $i<=60; $i+=5) {
        if ($age <= $i) return ($i-4 > 25 ? $i-4 : 0) . '-' . $i;
    }
    return '61-';
}

This should exactly give the desired output..so modulus was not a bad idea:

function calculateAgeGroup($age)
{
    if (!$age) { return null; }
    if ($age <= 25) { return '0-25'; }
    else if ($age > 50 && $age <= 60) { return '51-60'; }
    else if ($age > 60) { return '61-'; }
    $age = (($age%5) != 0) ? ($age - ($age%5) + 1) : ($age -= 4);
    return $age.'-'.($age+4);
}

Another option, where the values are precomputed:

function calculateAgeGroup($age)
{
    $age = ($age <= 25) ? 0 : ($age-1) - (($age-1) % 5);
    $age = ($age >= 60) ? 60 : $age;
    $ages = array (
        0 => '0-25', 25 => '26-30', 30 => '31-35',
        35 => '36-40', 40 => '41-45', 45 => '46-50',
        50 => '51-60', 55 => '51-60', 60 => '61-',
    );
    return $ages[$age];
}

I benchmarked the solutions and the first solution with modulus is the fastests from all provided answers since there is not much calculation involved.

It would be even faster if you take the array out of the function and make it global or as (static) class property.

$ages = array (
    0 => '0-25', 25 => '26-30', 30 => '31-35',
    35 => '36-40', 40 => '41-45', 45 => '46-50',
    50 => '51-60', 55 => '51-60', 60 => '61-',
);

function calculateAgeGroup($age)
{
    $age = ($age <= 25) ? 0 : ($age-1) - (($age-1) % 5);
    $age = ($age >= 60) ? 60 : $age;
    global $ages;
    return $ages[$age];
}

You can minimize your code using switch case or nested if elseif statement.

Using switch case:

function calculateAgeGroup($age)
{
    switch($age){
        case $age <= 25:
        return '0-25';
        break;

        case $age > 60:
        return '61-';
        break;

        default:
        if( $age/5 == 0 )
        $age = $age - 1;

        return (floor($age/5)*5).' - '.(ceil($age/5)*5);
        break;
    }
}

Using nested if elseif statement:

function calculateAgeGroup($age)
{
    if($age <= 25)
    return '0-25';
    elseif($age > 60)
    return '61-';
    else
    {
        if( $age/5 == 0 )
        $age = $age - 1;

        return (floor($age/5)*5).' - '.(ceil($age/5)*5);
    }
}

OR

function calculateAgeGroup($age)
{
    if($age <= 25)
    return '0-25';
    elseif($age > 60)
    return '61-';
    else
    {
        return ($age%5 == 0)?(floor(($age-1)/5)*5).'-'.(ceil(($age-1)/5)*5) : (floor($age/5)*5).'-'.(ceil($age/5)*5);
    }
}

I tested the code and both code more or less taking same time to execute.

Testing code-

$time_start = microtime(true); 
for($i=24;$i<62;$i++)
{
echo "Age $i :";
echo 'Age Group :'.calculateAgeGroup($i);
echo '<br>';
}
$time_end = microtime(true);
$execution_time = ($time_end - $time_start)/60;

//execution time of the script
echo '<b>Total Execution Time:</b> '.$execution_time.' Mins';
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top