Страницы

Поиск по вопросам

среда, 18 декабря 2019 г.

Функция для определения окончания слова по числительному (1 год, 2 года, 5 лет)

#php


Думаю, что вопрос актуальный. Во всех популярных сервисах данная фича есть. Порылся
в нете. Накатал небольшую функцию, но че-то подумал, может кто-нибудь на хэшкоде скажет
как будет сделать лучше?:) Хочется конечно, чтобы код работал быстро и со всеми числами
(будь то миллион, миллиард, трилион и т.д. :) )
Вот, мой вариант:
function getInclinationByNumber($number, $arr = Array()) {
    $number = (string) $number;
    $numberEnd = substr($number, -2);
    $numberEnd2 = 0;
    if(strlen($numberEnd) == 2){
        $numberEnd2 = $numberEnd[0];
        $numberEnd = $numberEnd[1];
    }

    if ($numberEnd2 == 1) return $arr[2];
    else if ($numberEnd == 1) return $arr[0];
    else if ($numberEnd > 1 && $numberEnd < 5)return $arr[1];
    else return $arr[2];
}
echo getInclinationByNumber(10,Array('тетрадь', 'тетради', 'тетрадей')).'
'; Если что, поправляйте)) Русский учил плохо, а стиль программирования, как вы уже поняли, оставляет желать лучшего))


Ответы

Ответ 1



Я пользуюсь такой function num2word($num, $words) { $num = $num % 100; if ($num > 19) { $num = $num % 10; } switch ($num) { case 1: { return($words[0]); } case 2: case 3: case 4: { return($words[1]); } default: { return($words[2]); } } } echo num2word(50, array('год', 'года', 'лет')); Тоже, что и у KiTE , но немного по-другому реализовано. =) Насколько я помню, можно еще 4 параметр передать. Типа год,года,лет,лет т.к. некоторые цифры определяются как, например, 2 параметр, а в русском языке звучат как третий. Пару раз сталкивался.

Ответ 2



Ололо. function number($n, $titles) { $cases = array(2, 0, 1, 1, 1, 2); return $titles[($n % 100 > 4 && $n % 100 < 20) ? 2 : $cases[min($n % 10, 5)]]; } echo number(631, array('яблоко', 'яблока', 'яблок'));

Ответ 3



Для Delphi как-то писал: function GetUnitCase(const AValue: Int64; const AUnit1, AUnit2, AUnit3: String): String; begin if (Abs(AValue) mod 100) in [11..19] then Result := AUnit3 else case Abs(AValue) mod 10 of 1: Result := AUnit1; 2..4: Result := AUnit2; else Result := AUnit3; end; end; Работает через вычисление остатка от деления. UPD: Вариант для PHP: function getUnitCase( $value, $unit1, $unit2, $unit3 ){ $value = abs( (int)$value ); if( ($value % 100 >= 11) && ($value % 100 <= 19) ){ return $unit3; }else{ switch( $value % 10 ){ case 1: return $unit1; case 2:case 3:case 4: return $unit2; default: return $unit3; } } } echo getUnitCase(33, 'рубль', 'рубля', 'рублей');

Ответ 4



/** * For the formation of endings of words. * echo $this->morph(count($this->comments), "комментарий", "комментария", "комментариев") * * @param int $value number. * @param string $word0 word in the singular. * @param string $word1 word in the plural (2, 3). * @param string $word2 word in the plural. * @param string $separator separator, default ' '. * @return string formed words * @access private. */ private function morph($value, $word0, $word1, $word2, $separator = ' ') { if (preg_match('/1\d$/', $value)) { return $value.$separator.$word2; } elseif (preg_match('/1$/', $value)) { return $value.$separator.$word0; } elseif (preg_match('/(2|3|4)$/', $value)) { return $value.$separator.$word1; } else { return $value.$separator.$word2; } }

Комментариев нет:

Отправить комментарий