28 января 2011

Урок. Функция склонения по числам

Давайте напишем функцию склонения по числам использовав switch. Эта функция будет, в зависимости от числа, ставить правильное окончание единице меры (тонна, килограмм, литр, штука). Поближе с функциями можете ознакомится в моем предыдущем уроке. И так, начнем:

Функция имеет вид:
function _chs($cifs, $ws){
   $wsk=explode("-", $ws);
   $cifsk=str_split($cifs); 
   $cm=count($cifsk)-2; 
   if($cifsk[$cm]==1)echo $cifs." ".$wsk[2];else{
       switch($cifsk[$cm+1]) {
       case "1": echo $cifs." ".$wsk[0]; break; 
       case $cifsk[$cm+1]>=5 || "0": echo $cifs." ".$wsk[2]; break;
       case $cifsk[$cm+1]<=4: echo $cifs." ".$wsk[1]; break;
       }
    }
}




Вызов функции осуществляется таким образом
_chs("32", "штука-штуки-штук");

Смотрим под лупой:
$wsk=explode(", ", $ws); # создание массива со значениями shtuka, shtuki, shtuk, использовав соответствующий разделитель "-"
$cifsk=str_split($cifs); # эта функция записывает каждый символ из переменной $cifs в ячейку массива $cifsk
$cm=count($cifsk)-2; # высчитывает количество ячеек массива и из полученного числа вычитает 2(то есть 32 это 3 и 2, то есть count получил цифру 2, а затем еще 2 минус 2, в итоге в переменной $c находится число 0)
if($cifsk[$cm]==1)echo $cifs." ".$wsk[2];else{ # если символ в ячейке №$cm (в данном случае $cm=0) равняется 1, тогда написать слово "штук", иначе:
switch($cifsk[$cm+1]) { # проверим переменную $cifsk[$cm+1] (в данном случае, при $cm=0, $cifsk[$cm+1] это всё равно что $cifsk[1], где в ячейке 1 хранится цифра 2)
 case "1": echo $cifs." ".$wsk[0]; break; # если 2==1, то написать слово "штука"
 case $cifsk[$cm+1]>=5 || "0": echo $cifs." ".$wsk[2]; break; # если 2>=5 или равно нулю, то написать "штук"
case $cifsk[$cm+1]<=4: echo $cifs." ".$wsk[1]; break; # если 2<=4, то написать "штуки", что и является правильным вариантом.}

Давайте возьмем лупу с зумом побольше и рассмотрим что и зачем делается:
мы написали:
$cifsk=str_split($cifs);

чтобы в дальнейшем узнать скольки-значное число, и какова у неё последняя цифра
Далее:
$cm=count($cifsk)-2;if($cifsk[$cm]==1)echo $cifs." ".$wsk[2];else{

благодаря этому мы выяснили не равняется ли предпоследняя цифра в числе одному, потому как если да, то тогда в любом случае надо писать "штук" (например 11 штук, 10914 штук, 18 штук и т.д.).
иначе проверяем последнюю цифру ($cm - это предпоследняя, а $cm+1 это уже соответственно последняя):
  switch($cifsk[$cm+1]){   case "1": echo $cifs." ".$wsk[0]; break;  
^если последняя цифра равняется одному то писать "штука"(Одна штука, 31 штука, 151 штука).

    case $cifsk[$cm+1]>=5 || "0": echo $cifs." ".$wsk[2]; break;
^если больше либо равно пяти, или же равняется нулю, то написать "штук" (145 штук, 9 штук, 37 штук)

   case $cifsk[$cm+1]<=4: echo $cifs." ".$wsk[1]; break;
^если меньше либо равно 4, то написать "штуки" (4 штуки, 103 штуки, 32 штуки)
можете поэкспериментировать с аргументами:
_chs("32", "тонна-тонны-тонн"); # вася весил 32 тонны
_chs("32", "литр кока-колы|литра кока-колы|литров кока-колы"); # вася выпил 32 литра кока-колы (используйте другой символ-разделить, если понадобится написать литр кока-колы, например измените в функции его на "|", либо пишите так: _chs("32", "литр-литра-литров")); echo " кока-колы";
_chs("32", "метр дальше-метра дальше-метров дальше"); # вася плюнул на 32 метра  дальше
_chs("32", "градус тепла-градуса тепла-градусов тепла"); # вася любит, когда в кладовке 32 градуса тепла

Давайте немного изменим функцию, чтобы она возвращала результат (о том, что это значит, вы можете узнать в моем предыдущем уроке)
 function _chs($cifs, $ws) {
   $wsk=explode("-", $ws);
   $cifsk=str_split($cifs);
   $cm=count($cifsk)-2; 
   if($cifsk[$cm]==1) $res=$cifs." ".$wsk[2];else{
      switch($cifsk[$cm+1]) {
      case "1": $res=$cifs." ".$wsk[0]; break; 
      case $cifsk[$cm+1]>=5 || "0": $res=$cifs." ".$wsk[2]; break; 
      case $cifsk[$cm+1]<=4: $res=$cifs." ".$wsk[1]; break; 
      }
   }return $res;
}
echo _chs("32", "штука-штуки-штук");



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

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

Лучшие сообщения