2012-05-23 2 views
2

У меня есть 2 массива, которые я хочу объединить на основе значения ключа в массиве 1. В приведенном ниже примере я хочу, чтобы game_modes помещались в games_list на основе ключа (id) в games_list.PHP слияния массивов на основе определенного ключа массива

Массив 1, который вытягивается из таблицы полного игра:

$games_list = array(
    0 => array(
    'id' => 23, 
    'name' => 'Call of Duty: Modern Warfare 3' 
    ), 
    2 => array(
    'id' => 1, 
    'name' => 'Call of Duty: Black Ops' 
    ) 
); 

Массива 2, который вытягивается из таблицы полных режимов игры:

$game_modes = array(
    0 => array(
    'id' => 1, 
    'game_id' => 1, 
    'description' => 'Capture the Flag' 
    ), 
    1 => array(
    'id' => 2, 
    'game_id' => 1, 
    'description => 'Domination' 
    ), 

    2 => array(
    'id' => 3, 
    'game_id' => 23, 
    'description' => 'Kill Confirmed' 
    ) 
); 

Я хотел бы результат будет :

$games_list = array(
    0 => array(
    'id' => 23, 
    'name' => 'Call of Duty: Modern Warfare 3' 
    'modes' => array(
     array(
      'id' => 3, 
      'game_id' => 23, 
      'description' => 'Kill Confirmed' 
     ) 
     ) 
    ), 
    2 => array(
    'id' => 1, 
    'name' => 'Call of Duty: Black Ops' 
    'modes'=> array(
     0 => array(
     'id' => 1, 
     'game_id' => 1, 
     'description' => 'Capture the Flag' 
     ), 
     1 => array(
     'id' => 2, 
     'game_id' => 1, 
     'description => 'Domination' 
     ) 
    ) 
    ) 
); 

Дополнительная информация, сайт, в котором я работаю, в настоящее время содержит 71 игр в своей базе данных и каждой игре может иметь какое-то произвольное количество игровых режимов.

Теперь я мог легко сделать кучу циклов и избежать этого вопроса. На данный момент у меня нет тонны игровых режимов, введенных в базу данных, но я все время добавляю все больше. Со временем, делая экспоненциально больше циклов, все время в конечном итоге сделает скорость загрузки страницы в обход.

Я потратил время, чтобы поместить эти данные в memcache, чтобы ускорить выполнение вызовов в будущем.

Я никогда не был хорошим с array_map, поскольку я не совсем понимаю, как это работает, или если это даже правильный маршрут.

ответ

3

Не думаете ли вы, что решение уровня запросов будет лучше? Длинный путь будет:

// array: $game_modes; 
// array: $game_lists; 

foreach ($game_modes as $gm=>$modes){ 
    if (isset($modes['game_id'])){ 
     foreach ($game_lists as $gl=>$lists){ 
     if ($lists['id'] == $modes['game_id']){ 
      $game_lists[$gl]['modes'][] = $modes; 
      //break; 
     } 
     } 
    } 
} 

Выход Категория: Резюме

$query = 'SELECT 
       g.id, g.name_name, 
       group_concat(gm.description) as descriptions 
      FROM games as g 
      LEFT JOIN games_modes as gm 
       ON g.id = gm.game_id 
      GROUP BY g.id'; 

Результат:

id | name      | descriptions 
------------------------------------------------------------ 
    1 | Call of Duty: Black Ops | Capture the Flag, Domination 

Выход Категория: Деталь

$query = 'SELECT 
       g.id, g.name_name, 
       gm.id, gm.description 
      FROM games as g 
      LEFT JOIN games_modes as gm 
       ON g.id = gm.game_id 
      ORDER BY g.id'; 

Результат:

id | name      | id | description 
----- --------------------------- ------- ------------------ 
    1 | Call of Duty: Black Ops | 1 | Capture the Flag 
    1 | Call of Duty: Black Ops | 2 | Domination 
+0

Я думал о делать это способ запроса, но тогда я бы кучу записей для каждой игры, основанной на количестве режимы игры. – Jayrox

+0

@Jayrox: Я все еще верю, что запрос был бы более эффективным способом. Можете ли вы предоставить соответствующую таблицу/поля? –

+0

таблица игр (id, game_name) games_modes table is (id, game_id, description) – Jayrox

0

Попробуйте уменьшить цикл

$cachearray = array(); 
foreach ($game_modes as $gm=>$modes){ 
    if(array_key_exists($modes['game_id'],$cachearray)) 
    { 
    $cachearray[$modes['game_id']]['modes'][] = $modes; 
    } 
    else   
    foreach ($games_list as $gl=>$lists){ 
     if ($lists['id'] == $modes['game_id']){ 
      $games_list[$gl]['modes'][] = $modes; 
      $cachearray[$lists['id']] = &$games_list[$gl]; 
      break; 
     } 
    } 
} 

print_r($games_list); 

Это будет легче, если у вас есть $games_list массив как этот

$games_list = array(
    23 => array(
    'id' => 23, 
    'name' => 'Call of Duty: Modern Warfare 3' 
    ), 
    1 => array(
    'id' => 1, 
    'name' => 'Call of Duty: Black Ops' 
    ) 
); 

И будет более мощным, используя запрос

+0

без выполнения цикла for, есть ли способ сделать запрос mysql сделать ключи с именем на основе их идентификатора, для вашего примера? – Jayrox

+0

@Jayrox Я не знаю, откуда взялся ваш массив. Но, если они отбирают, значит, есть способ. FYI, мой пример для вашей текущей ситуации в массиве. Но с моим '$ games_list', тогда вам не нужно' $ cachearray' в моем коде. –

+0

они исходят из таблицы mysql. игры (id, name) games_modes (id, game_id, description) – Jayrox

0

Если вы хотите получить карту массива пользователей, этот код должен быть возможен:

$ids = array_map(function($game) { return $game['id']; }, $games_list); 
$id_mapping = array_flip($ids);  

foreach($game_modes as $mode) { 
    if (array_key_exists($mode['game_id'], $id_mapping)) { 
     $games_list[$id_mapping[$mode['game_id']]]['modes'][] = $mode; 
    } 
} 

Но я не знаю, является ли это быстрее, чем два для циклов.

0

попробовать это:

$mode_map = array(); 
foreach($game_modes as $mode) 
{ 
    $game_id = $mode['game_id']; 
    if(!isset($mode_map[$game_id])) 
    { 
     $mode_map[$game_id] = array(); 
    } 

    $mode_map[$game_id][] = $mode; 
} 

foreach($games_list as &$game) 
{ 
    $game_id = $game['id']; 
    if(isset($mode_map[$game_id])) 
    { 
     $game['modes'] = $mode_map[$game_id]; 
    } 
} 

print_r($games_list); 

результат:

Array 
(
    [0] => Array 
     (
      [id] => 23 
      [name] => Call of Duty: Modern Warfare 3 
      [modes] => Array 
       (
        [0] => Array 
         (
          [id] => 3 
          [game_id] => 23 
          [description] => Kill Confirmed 
         ) 

       ) 

     ) 

    [2] => Array 
     (
      [id] => 1 
      [name] => Call of Duty: Black Ops 
      [modes] => Array 
       (
        [0] => Array 
         (
          [id] => 1 
          [game_id] => 1 
          [description] => Capture the Flag 
         ) 

        [1] => Array 
         (
          [id] => 2 
          [game_id] => 1 
          [description] => Domination 
         ) 

       ) 

     ) 

) 
Смежные вопросы