Функция очистки, которая помещает возраст в ведро возрастной группы-возможно?


У меня есть эта функция, которая классифицирует возраст пользователя в определенной возрастной группе:

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

Есть ли способ упростить (то есть: менее многословно, меньше утверждений if) это? Моя первая мысль была об использовании модуля, но я очень быстро отмахнулся от этого, так как здесь просто нет смысла использовать модуль.

Второй вариант был бы чем-то вроде floor($age/10)*10 . "-" . ceil($age/10)*10, но это также не работает во всех случаях.

Последним вариантом, который пришел мне в голову, было бы использование ряда () ? : утверждений что сделает код короче, но не более читабельным. Тоже не очень хорошо.

У кого-нибудь есть хорошая идея, как это упростить? Предложения приветствуются.
4 4

4 ответа:

Попробуйте этот код:

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

В качестве основы вы можете использовать следующий код для ваших инкрементов:

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

Это должно точно дать желаемое output..so модуль был неплохой идеей:

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

Другой вариант, где значения предварительно вычисляются:

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

Я провел сравнительный анализ решений, и первое решение с модулем является самым быстрым из всех представленных ответов, так как не требуется много вычислений.

Было бы еще быстрее, если бы вы взяли массив из функции и сделали его глобальным или как (статическое) свойство класса.

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

Вы можете свернуть свой код, используя switch case или вложенный оператор if elseif.

Используя 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;
    }
}

Используя вложенный оператор if elseif:

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

Или

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

Я протестировал код, и оба кода более или менее занимали одинаковое время для выполнения.

Тестовый код -

$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';