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.

有帮助吗?

解决方案

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;
    }
}

其他提示

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';
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top