Odmiana słowiańskich rzeczowników według liczb

Napisano: 4 sierpnia 2010 23:47 Aktualizowano: 4 sierpnia 2010 23:49

Odmiana rzeczowników w językach słowiańskich jest trochę bardziej skomplikowana niż w językach zachodnich. Z pierwszą próbą zetknąłem się dostosowując swój pierwszy moduł backendowy. Szukając sposobu przetłumaczenia nie tylko tekstów, ale i odmiany ich, natknąłem się na post: Plural forms and format_number_choice na forum symfony.

Znajdująca się tam formuła dla helpera format_number_choice() miała kilka wad, dlatego na podstawie istniejącej zaproponowałem własną, która radzi sobie ze wszystkimi wariacji liczb:

PHP code
'[0] brak|[1] 1 wynik|{n: n % 10 > 1 && n % 10 < 5 && ( n < 11 || n > 14 ) && ( n % 100 < 11 || n % 100 > 14 ) } %1% wyniki|[5,+Inf] %1% wyników '

Idąc dalej, stworzyłem funkcję biblioteczną, która przyjmuje w parametrach liczbę, oraz zestaw odmian rzeczownika, wybierając odpowiednią jego formę do liczby:

PHP code
  1. class Fizyk
  2. {
  3.     /**
  4.      * Function that returns proper inflection based on a number that describes it's quantity for slavic languages.
  5.  
  6.      * There are four forms: none, one singular and two plurar.
  7.      * $word array indexes 1, 2 and 3 are mandatory, while 0 is optional
  8.      * @param array $words
  9.      * @param integer $number
  10.      * @return string
  11.      * @author Grzegorz Śliwiński
  12.      */
  13.     static public function slavicWordFormNumberChoice( Array $words, $number)
  14.     {
  15.         //throw exception if passed array doesn't kontain 1st, 2nd or 3rd form
  16.         if( !array_key_exists( 1, $words) || !array_key_exists( 2, $words) || !array_key_exists( 3, $words ) )
  17.         {
  18.             //listing all keys
  19.             $keys = '';
  20.             foreach( array_keys( $words ) as $value )
  21.             {
  22.                 $keys .= $value.' ';
  23.             }
  24.             //throwning exception
  25.             throw new sfException( sprintf('Word array is incomplete! Should contain indexes 1, 2 and 3. Your contains: %s', $keys ) );
  26.         }
  27.  
  28.         //take care of the none case with word set
  29.         if( $number == 0 && array_key_exists(0, $words) )
  30.         {
  31.             return $words[0];
  32.         }
  33.         //take care of the none case without word set
  34.         elseif( $number == 0 && !array_key_exists(0, $words) )
  35.         {
  36.             $wordIndex = 3;
  37.         }
  38.         //One is always the same
  39.         elseif( $number == 1 )
  40.         {
  41.             $wordIndex = 1;
  42.         }
  43.         //Second case: numbers from x2 to x4 without those from x12 to x14 (x - any number)
  44.         elseif( $number % 10 > 1 && $number % 10 < 5 && ( $number < 11 || $number > 14 )
  45.                 && ( $number % 100 < 11 || $number % 100 > 14 ) )
  46.         {
  47.             $wordIndex = 2;
  48.         }
  49.         else
  50.         {
  51.             $wordIndex = 3;
  52.         }
  53.         //we return numbered phrase to the world
  54.         return $number.' '.$words[$wordIndex];
  55.     }
  56. }

Jedynym mankamentem tej metody jest konieczność zdefiniowania kluczy tablicy przekazywanych słów, ale akceptuje zestaw słów wszelakich.

Grzegorz Śliwiński

Skomentuj pierwszy!

Skomentuj!

Adres email nie zostanie opublikowany

Musi zaczynać się od http:// lub https://
Usuń odpowiedź