2012-05-23 70 views
2

我有两个数组,我想要根据数组1中的键值进行合并。在下面的示例中,我希望将game_list放入基于key(​​id)的games_list中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个游戏,每个游戏可以有一些任意数量的游戏模式。

现在,我可以轻松地做一堆for循环,并避免这个问题一起。截至目前,我没有大量的游戏模式进入数据库,但我一直在增加更多。随着时间的推移,指数级更多的循环将最终使页面加载速度陷入瘫痪。

我花时间将这些数据放入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表是(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查询使键命名基于他们的ID,为你的例子? – Jayrox

+0

@Jayrox我不知道你的数组来自哪里。但是,如果他们从提取这样有一个方法。仅供参考,我的例子是针对当前的阵列情况。但是用我的'$ 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; 
    } 
} 

但我不知道这是否比两个for循环更快。

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 
         ) 

       ) 

     ) 

)