Blog. Just Blog

Сейчас на сайте 2 гостей и 3 новостей

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Смешно звучит, правда? А ведь такие уродливые сочетания встречаются на очень многих сайтах. И если в английском языке достаточно написать что-то типа day(s), byte(s) и это будет смотреться вполне нормально, то в русском языке в конструкциях "число + слово" обязательно придется учитывать склонения. Безумные извраты типа "гостя(ей)" и "новость(ей)" я даже не рассматриваю, за такое надо лишать доступа к компьютеру навсегда.

Чтобы писать по-русски на своих сайтах я использую такую универсальную функцию:
  1. function num2word($num,$words) {
  2.   $num=$num%100;
  3.   if ($num>19) { $num=$num%10; }
  4.   switch ($num) {
  5.     case 1:  { return($words[0]); }
  6.     case 2:
  7.     case 3:
  8.     case 4:  { return($words[1]); }
  9.     default: { return($words[2]); }
  10.   }
  11. }
Параметры вызова: $num - число, $words - массив склонений нужного слова. Как формируется массив вы можете посмотреть на примерах.
  1. // Гостей
  2. $num1=2;
  3. $words1=Array("гость""гостя""гостей");
  4.  
  5. // Новостей 
  6. $num2=3;
  7. $words2=Array("новость""новости""новостей");
  8.  
  9. // Написать по-русски
  10. echo "Сейчас на сайте ";
  11. echo $num1." ".num2word($num1,$words1); // сколько гостей
  12. echo " и ";
  13. echo $num2." ".num2word($num2,$words2); // сколько новостей
Результат работы скрипта:

Сейчас на сайте 2 гостя и 3 новости

Чтобы было удобнее формировать массивы со склонениями, запомните ряд чисел 1-2-5, а потом мысленно подставляйте их в массив: (один "рубль", два "рубля", пять "рублей") или (одна "новость", две "новости", пять "новостей").

UPD. Провел небольшую оптимизацию, теперь функцию можно записать в одну строчку:
  1. function num2word($n,$words) {
  2.     return ($words[($n=($n=$n%100)>19?($n%10):$n)==1?: (($n>1&&$n<=4)?1:2)]);
  3. }


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 4194 | Комментариев: 13

Метки: PHP
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
amberlex (02.04.2013 в 12:14):
Классная функция, использую.
pav (20.02.2013 в 21:31):
Нужно еще добавить условие для дательного(вроде бы) падежа:
1 гостю понравилось это сообщение
2(3,4,5,9000) гостям не понравилось

У меня это так релизовано:
    public function getForm($num, array $forms) {
        switch (sizeof($forms)) {
            case 2: return $num == 1 ? $forms[0] : $forms[1];
            case 3:
                if (($num = $num % 100) > 19) {
                    $num = $num % 10;
                }
                switch ($num) {
                    case 1: return $forms[0];
                    case 2:
                    case 3:
                    case 4: return $forms[1];
                    default: return $forms[2];
                }
            default: return null;
        }
    }
openspace (14.01.2013 в 18:45):
спасибо!
magog (11.11.2012 в 00:47):
Ы! Как интересно, написал точно такую же функцию )))))
Только вот так вот объявил:

function num2word($n,$words=array(1,2,3)){ ... }
Олег (09.08.2011 в 05:40):
Спасибо.

Но я не понял почему

английском языке достаточно написать что-то типа day(s), byte(s) и это будет смотреться вполне нормально

Безумные извраты типа "гостя(ей)" и "новость(ей)" я даже не рассматриваю, за такое надо лишать доступа к компьютеру навсегда.
ManHunter (18.08.2010 в 15:10):
Угу, я бы посмотрел, что вернет ЭТО при входном значении $num=3 или $num=22
Роман (18.08.2010 в 15:08):
Или так:
function declination($num,$words)
{
if ( $num == 1 )
return ($words[0]);
if ( $num == 2 )
return ($words[1]);
if ( $num >= 5 )
return ($words[2]);
}
ManHunter (06.07.2010 в 01:53):
Можно вообще в одну строчку записать:

function num2word($n,$words) {
    return ($words[($n=($n=$n%100)>19?($n%10):$n)==1?0 : (($n>1&&$n<=4)?1:2)]);
}
ManHunter (28.03.2010 в 21:49):
Голова у солдата чтобы думать, а мозги, чтобы соображать.
Сергей Качалов (28.03.2010 в 17:49):
Похоже, данный скрипт никто не пытался использовать на практике. При числе более 9 он таки несколько усложнится.

Упс. Извиняюсь, невнимательно смотрел. :)
Гонщик (31.08.2009 в 15:17):
Всё гениальное - просто! Я когда-то давно писал нечто подобное, но было несколько сложнее. До такого упрощения тогда не додумался... Ещё раз спасибо.
64-ядерный процессор (23.06.2009 в 16:14):
Отличный скрипт! Малый размер, а результат весомый! :)
Павел (10.01.2009 в 06:35):
спасибо!

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0026 сек.) / Память: 4.5 Mb
Наверх