В русском языке существительные с числительными могут быть в единственном и множественном числе: один арбуз, два арбуза, пять арбузов. Различные существительные при склонении имяют разные окончания. Но, при сопряжении с числительным, у существительного может быть всего 3 формы с различными окончаниями.
Нам нужно выводить:
- 1 комментарий
- 2 комментария
- 3 комментария
- ...
- 6 комментариев
- ...
Задача 1. Написать PHP-функцию, которая это реализует.
<?php
/**
* Функция для получения правильных окончаний существительных при их использовании с числительными на php
*
* @param int $number Число (числительное)
* @param array $titles Массив слов для склонения
* @return string
**/
function plural($number, $titles){
$cases = array (2, 0, 1, 1, 1, 2);
return $titles[ ($number%100>4 && $number%100<20)? 2 : $cases[min($number%10, 5)] ];
}
$cmt = 2;
echo $cmt . ' ' . plural($cmt, array('комментарий', 'комментария', 'комментариев'));
// результат: 2 комментария
$cmt = 5;
echo $cmt . ' ' . plural($cmt, array('комментарий', 'комментария', 'комментариев'));
// результат: 5 комментариев
Немного оттюнингуем функцию plural таким образом, чтобы можно было передавать несколько слов. Это нужно, чтобы функцию можно было использовать даже тогда, когда от числительного зависит склонение сразу нескольких слов:
<?php
/**
* Функция для получения правильных окончаний слов на php
*
* @param int $number Число, к которому привязываемся
* @param array $titles Массив слов для склонения
* @return string
**/
function pluralTuning($number, array $titles) {
$cases = array(2, 0, 1, 1, 1, 2);
return sprintf($titles[ ($number%100>4 && $number%100<20)? 2 : $cases[min($number%10, 5)] ], $number);
}
$hour = 1;
echo $this->pluralTuning($hour, array("Остался %d час", "Осталось %d часа", "Осталось %d часов"));
// результат: Остался 1 час
$hour = 5;
echo $this->pluralTuning($hour, array("Остался %d час", "Осталось %d часа", "Осталось %d часов"));
// результат: Осталось 5 часов
Задача 2. Написать JS-функцию, которая это реализует.
function plural(number, titles) {
cases = [2, 0, 1, 1, 1, 2];
return titles[ (number%100>4 && number%100<20)? 2 : cases[(number%10<5)?number%10:5] ];
}
var cmt = 3;
// native js
document.getElementById('anyId').innerHTML = cmt + ' ' + plural(cmt, ['комментарий', 'комментария', 'комментариев']);
// using jquery
$('#anyId').html(cmt + ' ' + plural(cmt, ['комментарий', 'комментария', 'комментариев']));
// результат: 3 комментария
Впринципе нет ничего плохого в том, чтобы использовать приведенное решение, однако важно понимать, что его будет очень сложно масштабировать, особенно когда потребуется перевести сайт или приложение на другие языки.
Специально для таких простых задач, я разработал небольшой модуль на JavaScript, который позволяет склонять любые слова в зависимости от используемых числительных. Библиотека использует базу данных CLDR и таким образом работает практически с любым языком в мире. Она называется — Numerous.
Также, я написал небольшую статью о том, как можно ей воспользоваться: «How to pluralize any word in different languages using JavaScript?»: Извиняюсь, что на английском, но суть должна быть понятна.
Буду очень рад, если она Вам пригодится. Также буду рад любым отзывам и предложениям! Удачных склонений!
Использование модуля выглядит очень симпатично:
russianPluralizer.pluralize(2, {one: 'яблоко',
few: 'яблока',
many: 'яблок'
});
Правда, дополнительные скрипты подключать надо (numerous.js и locales).
Если нужно склонять именно на js, то, думаю, будет самое то.