Склонение существительных

Здравствуйте! Недавно столкнулся с задачей склонения существительных после числовых значений, например 1 удав, но 2 удава. Прежде чем лезть в просторы интернета за готовыми вариантами решений, мне захотелось самому понять принцип склонения существительных.

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

0 -ов 10 -ов 20 -ов
1 11 -ов 21
2 12 -ов 22
3 13 -ов 23
4 14 -ов 24
5 -ов 15 -ов 25 -ов
6 -ов 16 -ов 26 -ов
7 -ов 17 -ов 27 -ов
8 -ов 18 -ов 28 -ов
9 -ов 19 -ов 29 -ов

Из данной таблицы можно понять, что:

  1. Вариантов возможных окончаний три.
  2. Окончания повторяются циклично в зависимости от последней цифры числа.
  3. Числа 11-14 выбиваются из общего принципа склонения существительных

Следовательно получается, если взять последние две цифры числительного и получившееся число находится в диапазоне 11-14 включительно, то окончание должно быть «-ов», во всех остальных случаях для определения окончания будет достаточно одной последней цифры числа.

окончание «-ов», если последняя цифра 0 (ноль) либо 5-9

окончание «-«, если последняя цифра 1

окончание «-а», если окончание 2-4

Теперь общий принцип вычисления окончания думаю стал понятен, можно приступить к программированию. Наиболее интересным и лаконичным решением мне показался следующий код, найденный на сайте expange.ru и слегка преобразованный.


public static function numberEnd($number, $value, $suffix)
{
   //ключи массива suffix
   $keys = array(2, 0, 1, 1, 1, 2);

   //берем 2 последние цифры
   $mod = $number % 100;

   //определяем ключ окончания
   $suffix_key = $mod > 4 && $mod < 21 ? 2 : $keys[min($mod%10, 5)];

   return $value . $suffix[$suffix_key];
}

Суть данного кода в следующем.

$sufix массив возможных окончаний, выставленных в порядке соответствия числительным 1, 2, 5.

$keys содержит ключи массива окончаний соответствующие числительным 0-5.

Как мы уже выяснили выше, для того чтобы узнать окончание по последней цифре, нужно выяснить не заканчивается ли число на 11-14.  Но поскольку мы берем 2 цифры и из таблицы видно, что диапазон окончаний у числительных 11-14 попадает в более обширный диапазон 5-20, поэтому во время проверки возьмем его.

Если число не попадает под наш диапазон, то берем от него последнюю цифру и проверяем так, если бы это было число в диапазоне 0-9.

min($mod%10, 5) Поскольку окончания после числительного 5 идут одинаковые (в пределах диапазона 0-9), то выполняется сравнение с пятеркой и указывается в массиве ключей.

Пример использования

 echo numberEnd(7, 'удав', array('', 'а', 'ов'));

7 удавов

 echo numberEnd(1, 'запис', array('ь', 'и', 'ей'));

1 запись

Удачи!

comments powered by HyperComments
Евгений
2016-06-25 15:14:00
Добрый день. А как все это можно преобразовать в вордпресовский шорткод? У меня есть шорткод, который выводит количество записей в категории: /* Шорткод кол-ва записей */ function kol_zap($atts) { extract(shortcode_atts(array( "id" => '' ), $atts)); $post_count = get_category($id)->category_count; $cat_name = get_category($id)->name; $cat_slug = get_category($id)->slug; return ''.$post_count.''; } add_shortcode('kolvo', 'kol_zap'); Хотелось, чтобы этот шорткод выводил после числа - слово запиь('и', 'ей'). Заранее спасибо.
При копировании материалов обратная ссылка на play-stop.ru желательна обязательна!