Склонение слова по числу (PHP)

Форум для тех кто начинает осваивать язык php.
lyod
Сообщения: 76
Поблагодарили: 1 раз

Склонение слова по числу (PHP)

Сообщение lyod » Ср апр 15, 2015 10:06 pm

Здравствуйте! Очень часто мы с Вами видим на сайтах подобные надписи:
У Вас на счету 51 рублей.

Согласитесь, совсем некрасиво, когда слово, которое следует за цифрой, не соответствует склонению, которое требуется в данном контексте.
Так вот, чтобы Вы делали красивые предложения :), представляю Вам очень простую, но полезнейшую функцию, которая возвращает нам слово, склонив его в правильном падеже:

Код: Выделить всё

/**
    * Для склонения слова по числу
    * @param string $word - часть слова, общая для всех окончаний
    * @param array $ends - массив окончаний
    * @param integer $amount - число, по которому склоняем
    *
    * @return string
    */
    function declination( $word, array $ends, $amount ){       
        # Делим количество и получаем остаток
        $rest = $amount % 10;
       
        # Вычисляем ключ массива (какое окончание вставлять)
        $end = $rest >= 2 && $rest < 5 ? 1 : ($rest > 2 ? 2 : 0);
       
        # Возвращаем окончание
        return
            isset( $ends[$end] ) ? $word . $ends[$end] : $word;
    }

Пользоваться очень просто:

Код: Выделить всё

# Выведется: "Я говорю, что у меня 3 машины"
echo 'Я говорю, что у меня 3 ' . declination('машин', ['а','ы'], 3);

Как видите, ничего сложного! Первым аргументом в функцию мы передаём часть слова, которая является общей для всех окончаний. Вторым аргументом мы передаём массив окончаний (первый элемент - окончание для числа с единицей на конце, второй для числа до с окончанием до четырёх, и третий (необязательный, в случае, если общая часть подходит для чисел с числом на конце от 5 до 9) - для чисел с числом на конце от 5 до 9). Последним аргументом в функцию мы передаём само число, о котором ведётся речь в предложении.
Несколько примеров для закрепления:

Код: Выделить всё

    # Выведет: У нас на реке 5 лодок
    echo 'У нас на реке 5 ' . declination('лод', ['ка','ки','ок'], 5);
   
    # Выведет: У нас на реке 3 лодки
    echo 'У нас на реке 3 ' . declination('лод', ['ка','ки','ок'], 3);
   
    # Выведет: У нас на реке 1 лодка
    echo 'У нас на реке 1 ' . declination('лод', ['ка','ки','ок'], 1);

Вот так. Пользуйтесь :).
Реклама
lyod
Сообщения: 76
Поблагодарили: 1 раз

Re: Склонение слова по числу (PHP)

Сообщение lyod » Чт апр 16, 2015 10:03 am

Добавил маленькое условие, что функция корректно срабатывала на ноль:

Код: Выделить всё

/**
    * Для склонения слова по числу
    * @param string $word - часть слова, общая для всех окончаний
    * @param array $ends - массив окончаний
    * @param integer $amount - число, по которому склоняем
    *
    * @return string
    */
    function declination( $word, array $ends, $amount ){       
        # Делим количество и получаем остаток
        $rest = $amount % 10;
       
        # Вычисляем ключ массива (какое окончание вставлять)
        $end = $rest >= 2 && $rest < 5 ? 1 : (!$rest || $rest > 2 ? 2 : 0);
       
        # Возвращаем окончание
        return
            isset( $ends[$end] ) ? $word . $ends[$end] : $word;
    }
lyod
Сообщения: 76
Поблагодарили: 1 раз

Re: Склонение слова по числу (PHP)

Сообщение lyod » Чт апр 16, 2015 11:03 pm

Эх, не учёл я цифры от 11 до 19, в них совсем по другому склоняется. Вот исправленный вариант :)

Код: Выделить всё

/**
    * Для склонения слова по числу
    * @param string $word - часть слова, общая для всех окончаний
    * @param array $ends - массив окончаний
    * @param integer $amount - число, по которому склоняем
    *
    * @return string
    */
    function declination( $word, array $ends, $amount ){       
        # Делим количество на сто и получаем остаток
        $rest = $amount % 100;
       
        # Делим количество на десять и получаем остаток
        $decimal = $rest % 10;

        # Вычисляем ключ массива (какое окончание вставлять)
        $end = $rest < 10 && $decimal >= 2 && $decimal < 5 ? 1 : (!$decimal || $decimal > 2 || $rest > 10 && $rest < 20 ? 2 : 0);
       
        # Возвращаем окончание
        return
            isset( $ends[$end] ) ? $word . $ends[$end] : $word;
    }

Хотя, кажется, можно было и короче. :D

Вернуться в «PHP»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя