За последние 24 часа нас посетили 22173 программиста и 1154 робота. Сейчас ищут 320 программистов ...

Упростить код с одинаковым действием для нескольких условий

Тема в разделе "Прочие вопросы по PHP", создана пользователем Вероломство, 11 мар 2021.

  1. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    Есть один супер декоратор :) у меня

    PHP:
    1. public function getDefense($country_code)
    2. {
    3.     // Германия - бонус наземной техники
    4.     if ($country_code == 'de' and $this->type == 'ground') {
    5.         $this->defense *= 1.2;
    6.     }
    7.  
    8.     // Россия - бонус морской техники
    9.     if ($country_code == 'ru' and $this->type == 'marine') {
    10.         $this->defense *= 1.2;
    11.     }
    12.  
    13.     // США - бонус воздушной техники
    14.     if ($country_code == 'us' and $this->type == 'air') {
    15.         $this->defense *= 1.2;
    16.     }
    17.  
    18.     // Если нет изменений, то Китай, Казахстан, Украина, Беларусь: значение по дефолту
    19.     return $this->defense;
    20. }
    Что не нравится: мозолят глаза однотипные вроде как условия с одинаковым действием.

    Есть идея в скобках через OR их все запилить в одно условие, но может у кого-то опыта побольше и есть какие-нибудь покруче наработки, поделитесь.
     
  2. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Проверка существования ключей в многомерном массивe.
    PHP:
    1. if(isset($array[$country_code][$this->type]))  $this->defense *= $array[$country_code][$this->type];
     
    Вероломство нравится это.
  3. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @Drunkenmunky только теперь в массиве повторы - 1.2

    PHP:
    1. public function getDefense($country_code)
    2. {
    3.     $array = ['de' => ['ground' => 1.2], 'ru' => ['marine' => 1.2], 'us' => ['air' => 1.2]];
    4.  
    5.     if (isset($array[$country_code][$this->type])) {
    6.         $this->defense *= $array[$country_code][$this->type];
    7.     }
    8.  
    9.     return $this->defense;
    10. }
    хотя нормально вроде, вдруг там бонус меняться будет или разный для каждой страны, оставлю пожалуй так
     
    #3 Вероломство, 11 мар 2021
    Последнее редактирование: 11 мар 2021
  4. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Ну, так, если у вас вне зависимости от условий $this->defense *= 1.2 зачем вы вообще их проверяете?
     
  5. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    это где так у меня? :)

    у меня 7 стран и три типа техники, 20% бонус только трём странам на определённую техну, если условие(я): {страна-техника} не совпали, то дефолт вернёт без бонуса ЖЕ

    я УЖЕ подумал что на случай изменения размера(ов) бонуса то подойдёт и с таким массивом
     
  6. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Здесь:
     
  7. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    ты обрезал код :)

    там в конце метода

    PHP:
    1. // Если нет изменений, то Китай, Казахстан, Украина, Беларусь: значение по дефолту
    2. return $this->defense;
    --- Добавлено ---
    @Drunkenmunky понял?

    дефолт 100

    если например Россия, то 120, если Беларусь, то 100 так и вернётся

    условие изменяет возвращаемое значение свойства при совпадении
     
  8. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Тогда еще проще.
    Два массива - со страной и техникой, если оба параметра присутствуют и там и там, то бонус.
    in_array() в помощь.
     
  9. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    ага, мне эта мысль как раз тоже мелькнула, когда я массив под твой пример рисовал, тоже надо попробовать, спс...
    --- Добавлено ---
    @Drunkenmunky твой пример хорош тем, что можно отдельно под каждую страну бонус назначить
     
  10. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Я так сначала и понял.
     
    Вероломство нравится это.
  11. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    а я наоборот глухо забил по 1.2, а теперь думаю ё-маё, так можно же будет менять :)

    чёт тупанул, ок, вроде порешали
     
  12. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    PHP:
    1. public function getDefense( string $country_code )/* : int | float */
    2. {
    3.     $a = array_fill_keys ( [ 'de#ground', 'ru#marine', 'us#air' ], 1.2 );
    4.  
    5.     if ( isset ( $a[$country_code . '#' . $this -> type] ) )
    6.     {
    7.         $this->defense *= $a[$country_code . '#' . $this -> type];
    8.     }
    9.  
    10.     return $this -> defense;
    11. }
    12.  
    13. public function getDefense( string $country_code )/* : int | float */
    14. {
    15.     if ( in_array ( $country_code . '#' . $this -> type, [ 'de#ground', 'ru#marine', 'us#air' ], true ) )
    16.     {
    17.         $this -> defense *= 1.2;
    18.     }
    19.  
    20.     return $this -> defense;
    21. }
     
    #12 MouseZver, 11 мар 2021
    Последнее редактирование: 11 мар 2021
    Вероломство нравится это.
  13. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    PHP 8
    PHP:
    1. public function getDefense( string $country_code ): int | float
    2. {
    3.     return match ( $country_code . '#' . $this -> type )
    4.     {
    5.         'de#ground', 'ru#marine', 'us#air' => $this -> defense *= 1.2,
    6.         'kr#power' => $this -> defense *= 100500,
    7.         default => $this -> defense,
    8.     };
    9. }
    2021-03-11_13-06-26.png
     
    Вероломство нравится это.
  14. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @MouseZver благодарю, буду пробовать :)

    подтолкнули в этой теме меня смотреть в сторону массивов, нашёл я такую вот функцию: возыращает ключ совпадающего значения, я не фанат работы с массивами, правильно ли я применил функцию?

    PHP:
    1. public function getDefense($country_code)
    2. {
    3.     if ($country_code == array_search($this->type, ['de' => 'ground', 'ru' => 'marine', 'us' => 'air'])) {
    4.         $this->defense *= 1.2;
    5.     }
    6.  
    7.     return $this->defense;
    8. }
    --- Добавлено ---
    @MouseZver мне варик с in_array приколол больше всего, я таких фокусов ещё не видел :)
     
  15. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    array_search - медленный
    in_array - менее медленный
    isset - fast
    match - неизвестно. При тесте нужно учитывать громоздкость кода, быстродействие, меньше php действий = лучше, удобность кодинга
    --- Добавлено ---
    Для примера:
    PHP:
    1. if ( $array != [] ) {}
    2. if ( empty ( $array ) ) {} // на 40% быстрее работает
     
    Вероломство нравится это.
  16. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @MouseZver я на 7.4 сижу, забрал варик с in_array, всё гениальное - просто, блин это же надо: тупо конкатенировать и сравнить, я чёт не допёр, нормально так :)