Окончания существительных при использовании их с числительными на php и js

В русском языке существительные с числительными могут быть в единственном и множественном числе: один арбуз, два арбуза, пять арбузов. Различные существительные при склонении имяют разные окончания. Но, при сопряжении с числительным, у существительного может быть всего 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 комментария

 

 
 
 
 

icon Комментарии 2

 sfomin 8 лет назад
Благодарю за статью!

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

Специально для таких простых задач, я разработал небольшой модуль на JavaScript, который позволяет склонять любые слова в зависимости от используемых числительных. Библиотека использует базу данных CLDR и таким образом работает практически с любым языком в мире. Она называется — Numerous.

Также, я написал небольшую статью о том, как можно ей воспользоваться: «How to pluralize any word in different languages using JavaScript?»: Извиняюсь, что на английском, но суть должна быть понятна.

Буду очень рад, если она Вам пригодится. Также буду рад любым отзывам и предложениям! Удачных склонений!
 root 8 лет назад
sfomin, спасибо за ссылку!
Использование модуля выглядит очень симпатично:
russianPluralizer.pluralize(2, {
one: 'яблоко',
few: 'яблока',
many: 'яблок'
});

Правда, дополнительные скрипты подключать надо (numerous.js и locales).
Если нужно склонять именно на js, то, думаю, будет самое то.
Ваш комментарий к статье.. (для авторизованных)

ctrl+enter

icon Вход в систему

зарегистрироваться
НОВЫЕ ПОЛЬЗОВАТЕЛИ