Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Преобразование многомерного массива

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Мозговой штурм - многомерные массивы
Prizma
Отправлено: 16 Сентября, 2018 - 16:50:22
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




Добрый день,
в ходе работы потребовалось решить интересную задачку, решил поделится с аудиторией моего любимого форума.
Сразу к делу:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. class CpcData
  3. {
  4.  
  5.     // [source][type][campaign][ads][keyword][position] => amount
  6.     private $referrers = [
  7.         'google' => [ // source
  8.             'cpc' => [ // type
  9.                 'context' => [ // campaign
  10.                     123456789 => [ // ads
  11.                         'ключевое слово' => [ // keyword
  12.                                 2 => 10       // position => amount
  13.                         ]
  14.                     ],
  15.                     123456790 => [
  16.                         'другое ключевое слово' => [
  17.                                 1 => 5
  18.                         ]
  19.                     ]
  20.                 ],
  21.                 'retarget' => [
  22.                     123456791 => [
  23.                         'ключевое слово' => [
  24.                             0 => 11
  25.                         ]
  26.                     ],
  27.                     123456792 => [
  28.                         'другое ключевое слово' => [
  29.                             0 => 32
  30.                         ]
  31.                     ]
  32.                 ]
  33.             ]
  34.         ],
  35.         'yandex' => [ // source
  36.             'cpc' => [ // type
  37.                 'context' => [ // campaign
  38.                     223456789 => [ // ads
  39.                         'ключевое слово' => [ // keyword
  40.                             2 => 10       // position => amount
  41.                         ]
  42.                     ],
  43.                     223456790 => [
  44.                         'другое ключевое слово' => [
  45.                             1 => 5
  46.                         ]
  47.                     ]
  48.                 ],
  49.                 'retarget' => [
  50.                     223456791 => [
  51.                         'ключевое слово' => [
  52.                             0 => 3
  53.                         ]
  54.                     ],
  55.                     223456792 => [
  56.                         'другое ключевое слово' => [
  57.                             0 => 22
  58.                         ]
  59.                     ]
  60.                 ]
  61.             ]
  62.         ]
  63.     ];
  64.  
  65.     /**
  66.      * Если все параметры === null:
  67.      * return $this->referrers;
  68.      * Eсли все параметры !== null:
  69.      * return isset($this->referrers[$p1][$p2][$p3][$p4][$p5][$p6]) ? $this->referrers[$p1][$p2][$p3][$p4][$p5][$p6] : 0;
  70.      * Иначе фильтрует массив по параметрам !== null уменьшая его многомерность по известным звеньям:
  71.      * // частный пример №1
  72.      * $p1 = 'x'; $p2 = 'y'; // $p1 - source, $p2 - type
  73.      * return isset($this->referrers[$p1][$p2]) ? $this->referrers[$p1][$p2] : [];
  74.      * // частный пример №2
  75.      * $type = 'x'; // p2
  76.      * $rf = $this->referrers;
  77.      * foreach($rf as $source => $types) {
  78.      *  if(isset($types[$type])) {
  79.      *      $rf[$source] = $types[$type];
  80.      *  }else{
  81.      *      unset($rf[$source]);
  82.      *  }
  83.      * }
  84.      * return $rf;
  85.      */
  86.     public function getReferrers($source = null, $type = null, $campaign = null, $ads = null, $keyword = null, $position = null)
  87.     {
  88.         if($source !== null && $type !== null && $campaign !== null && $ads !== null && $keyword !== null && $position !== null) {
  89.             $rf = $this->referrers;
  90.             return isset($rf[$source][$type][$campaign][$ads][$keyword][$position]) ?
  91.                 $rf[$source][$type][$campaign][$ads][$keyword][$position] : 0;
  92.         }elseif ($source !== null || $type !== null || $campaign !== null || $ads !== null || $keyword !== null || $position !== null) {
  93.             /**
  94.              * обработка всех остальных случаев
  95.              */
  96.         }else{
  97.             return $this->referrers;
  98.         }
  99.     }
  100. }
  101. ?>

PS: данные грузятся не из бд, а из локальных файлов, массив достаточно объемный, для вывода, обрабатывается 20-30 файлов в каждом из которых такой массив забитый данными посещений за неделю, из данных генерируются графики отражающие те или иные показатели

PPS: думаю сегодня завтра выложу своё решение, не знаю будет ли оно достаточно производительным для поставленных задач.
 
My status
 Top
Мелкий Супермодератор
Отправлено: 16 Сентября, 2018 - 18:10:21
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




А где сама задача-то?


-----
PostgreSQL DBA
 
 Top
Prizma
Отправлено: 16 Сентября, 2018 - 19:09:51
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




Мелкий пишет:
А где сама задача-то?

Там где приведено 2 частных примера, нужно написать участок кода, который бы работал для всех пяти аргументов, независимо сколько и какие из них == null. Примеры приведены исключительно для конкретизации результата.
(Добавление)
Решение оказалось достаточно простым, производительность вроде должна быть норм - посмотрим:
Спойлер (Отобразить)

Полный код:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. class CpcData
  3. {
  4.     // [source][type][campaign][ads][keyword][position] => amount
  5.     private $referrers = [
  6.         'google' => [ // source
  7.             'cpc' => [ // type
  8.                 'context' => [ // campaign
  9.                     123456789 => [ // ads
  10.                         'ключевое слово' => [ // keyword
  11.                                 2 => 10       // position => amount
  12.                         ]
  13.                     ],
  14.                     123456790 => [
  15.                         'другое ключевое слово' => [
  16.                                 1 => 5
  17.                         ]
  18.                     ]
  19.                 ],
  20.                 'retarget' => [
  21.                     123456791 => [
  22.                         'ключевое слово' => [
  23.                             0 => 11
  24.                         ]
  25.                     ],
  26.                     123456792 => [
  27.                         'другое ключевое слово' => [
  28.                             0 => 32
  29.                         ]
  30.                     ]
  31.                 ]
  32.             ]
  33.         ],
  34.         'yandex' => [ // source
  35.             'cpc' => [ // type
  36.                 'context' => [ // campaign
  37.                     223456789 => [ // ads
  38.                         'ключевое слово' => [ // keyword
  39.                             2 => 10       // position => amount
  40.                         ]
  41.                     ],
  42.                     223456790 => [
  43.                         'другое ключевое слово' => [
  44.                             1 => 5
  45.                         ]
  46.                     ]
  47.                 ],
  48.                 'retarget' => [
  49.                     223456791 => [
  50.                         'ключевое слово' => [
  51.                             0 => 3
  52.                         ]
  53.                     ],
  54.                     223456792 => [
  55.                         'другое ключевое слово' => [
  56.                             0 => 22
  57.                         ]
  58.                     ]
  59.                 ]
  60.             ]
  61.         ]
  62.     ];
  63.  
  64.     /**
  65.      * Если все параметры === null:
  66.      * return $this->referrers;
  67.      * Eсли все параметры !== null:
  68.      * return isset($this->referrers[$p1][$p2][$p3][$p4][$p5][$p6]) ? $this->referrers[$p1][$p2][$p3][$p4][$p5][$p6] : 0;
  69.      * Иначе фильтрует массив по параметрам !== null уменьшая его многомерность по известным звеньям:
  70.      * // частный пример №1
  71.      * $p1 = 'x'; $p2 = 'y'; // $p1 - source, $p2 - type
  72.      * return isset($this->referrers[$p1][$p2]) ? $this->referrers[$p1][$p2] : [];
  73.      * // частный пример №2
  74.      * $type = 'x'; // p2
  75.      * $rf = $this->referrers;
  76.      * foreach($rf as $source => $types) {
  77.      *  if(isset($types[$type])) {
  78.      *      $rf[$source] = $types[$type];
  79.      *  }else{
  80.      *      unset($rf[$source]);
  81.      *  }
  82.      * }
  83.      * return $rf;
  84.      */
  85.     public function getReferrers($source = null, $type = null, $campaign = null, $ads = null, $keyword = null, $position = null)
  86.     {
  87.         if($source !== null && $type !== null && $campaign !== null && $ads !== null && $keyword !== null && $position !== null) {
  88.             $rf = $this->referrers;
  89.             return isset($rf[$source][$type][$campaign][$ads][$keyword][$position]) ?
  90.                 $rf[$source][$type][$campaign][$ads][$keyword][$position] : 0;
  91.         }elseif ($source !== null || $type !== null || $campaign !== null || $ads !== null || $keyword !== null || $position !== null) {
  92.             $keys = [$source, $type, $campaign, $ads, $keyword, $position];
  93.             $refs = $this->referrers;
  94.             $this->arrayParser($refs, $keys);
  95.             return $refs;
  96.         }else{
  97.             return $this->referrers;
  98.         }
  99.     }
  100.  
  101.     private function arrayParser(array &$ar, array $keys)
  102.     {
  103.         $i = 0; // index of $key
  104.         foreach ($keys as $key) {
  105.             $i++;
  106.             if($key === null) {
  107.                 // проверяем остались ли еще ключи
  108.                 if(count($keys) > $i) {
  109.                     // Передаём каждый элемент на проверку по оставшимся ключам
  110.                     foreach ($ar as $k => &$v) {
  111.                         $this->arrayParser($v, array_slice($keys, $i));
  112.                         if($v === []) {
  113.                             unset($ar[$k]);
  114.                         }
  115.                     }
  116.                 }
  117.                 // Прекращаем обработку ключей, оставшиеся ключи обработает рекурсия
  118.                 break;
  119.             }else{
  120.                 if(isset($ar[$key])) {
  121.                     // убираем лишний уровень вложенности
  122.                     $ar = $ar[$key];
  123.                 }else{
  124.                     $ar = [];
  125.                     // Не найдено соответствий, прекращаем последующий поиск
  126.                     break;
  127.                 }
  128.             }
  129.         }
  130.     }
  131. }
  132. ?>

Проверка:
PHP:
скопировать код в буфер обмена
  1. $a = new CpcData();
  2. $rf = $a->getReferrers('yandex', 'cpc', 'context', 223456789, 'ключевое слово', 2);
  3. var_dump($rf); // int 10
  4. $rf = $a->getReferrers(null, 'cpc', 'context', 223456789, 'ключевое слово', 2);
  5. var_dump($rf); // array (size=1) 'yandex' => int 10
  6. $rf = $a->getReferrers('yandex', null, null, 223456789, 'ключевое слово', 2);
  7. var_dump($rf);
  8. /*
  9. array (size=1)
  10.   'cpc' =>
  11.     array (size=1)
  12.       'context' => int 10
  13.  */
  14. $rf = $a->getReferrers('yandex', null, null, null, 'ключевое слово', 2);
  15. var_dump($rf);
  16. /*
  17. array (size=1)
  18.   'cpc' =>
  19.     array (size=1)
  20.       'context' =>
  21.         array (size=1)
  22.           223456789 => int 10
  23.  */
  24. $rf = $a->getReferrers(null, 'cpc', 'retarget', null, null, 0);
  25. var_dump($rf);
  26. /*
  27. array (size=2)
  28.   'google' =>
  29.     array (size=2)
  30.       123456791 =>
  31.         array (size=1)
  32.           'ключевое слово' => int 11
  33.       123456792 =>
  34.         array (size=1)
  35.           'другое ключевое слово' => int 32
  36.   'yandex' =>
  37.     array (size=2)
  38.       223456791 =>
  39.         array (size=1)
  40.           'ключевое слово' => int 3
  41.       223456792 =>
  42.         array (size=1)
  43.           'другое ключевое слово' => int 22
  44.  */

(Отредактировано автором: 16 Сентября, 2018 - 20:03:50)

 
My status
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB