Сегодня надо было решить одну задачку, а именно — вывести цифру и слово, у которого окончание зависит от числа. 5 Человек, 3 человека, 1928 человек и так далее. Самих чисел может быть сколько угодно.
Полез в нет за готовым решением, нашел там одни циклы по условию
if( тут всякие деления по модулю == столько то){
то вывести так}
if( тут еще как нибудь){
вывести так}
Или тоже самое, но вариант switch … case…
Крайне громоздко, особенно если требуется вывести строку только в одном месте.Ну и работает до определенного потолка — если число будет миллион, то надо либо внутри цикла циклом цифру для умножения увеличивать, либо прописывать с руки все варианты.
Еще есть вариант забить все данные в массив и там искать нужную пару значений:
$array = (
"1", "человек",
"2", "человека",
....
if(in_array(....
Проблемы те же, надо либо генерить все возможные варианты, либо какую то хитрую функцию писать, чтобы искать там.
Еще один знакомый прогер подсказал вариант с ngettext. Но там также надо колдовать с расчетами:
<?php
/**
* Returns:
* 0, if $n == 1, 21, 31, 41, ...
* 1, if $n == 2..4, 22..24, 32..34, ...
* 2, if $n == 5..20, 25..30, 35..40, ...
*/
function plural( $n )
{
if ( $n % 10 == 1 && $n % 100 != 11 )
{
return 0;
}
if ( $n % 10 >= 2 && $n % 10 <= 4 && ( $n % 100 < 10 || $n % 100 >= 20 ) )
{
return 1;
}
return 2;
}
// usage
for ( $i = 0; $i < 100; $i++ )
{
$x = plural( $i );
printf(
"%d тетрад%s<br/>\n", $i,
( 0 == $x ? 'ь' : ( 1 == $x ? 'и' : 'ей' ) )
);
}
?>
Output:
0 тетрадей
1 тетрадь
2 тетради
3 тетради
4 тетради
5 тетрадей
6 тетрадей
7 тетрадей
8 тетрадей
9 тетрадей
10 тетрадей
...
Also here is short version:
<?php
$n = 17;
print ($n%10==1 && $n%100!=11 ? 0 : ($n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2));
?>
output: 2
Тут один фиг на 100 делится, большие числа ну никак не пролезут. Мой вариант, делает тоже самое, только без ограничения на число, вычисляет по последней цифре:
$result = '19321';
$mess = preg_replace("(2|3|4)","тетради", substr($result, -1));
((substr($mess, -1) * 1) > 1 OR (substr($mess, -1) * 1) == 0) ? $mess = "тетрадей" : $mess = "тетрадь";
echo $result . ' ' .$mess;
В одну строку так и не сумел придумать ((
UPD А вот сумел
echo (( (substr($str, -1) * 1) 1)) ? "тетради" : ( (( (substr($str, -1) * 1) == 0) OR ( (substr($str, -1) * 1) > 4)) ? "тетрадей" : "тетрадь" );
И полезный линк на тернарный оператор