PHP根据特定的数组键合并数组

时间:2012-05-23 02:49:28

标签: php arrays

我想根据数组1中的键值合并2个数组。在下面的示例中,我希望game_modes根据games_list中的键(id)放入games_list。

阵列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循环并一起避免这个问题。截至目前,我没有输入数据库的大量游戏模式,但我一直在增加更多。随着时间的推移,指数越来越多的循环最终会使页面加载速度变得爬行。

我花了很多时间将这些数据放入内存缓存中,以便日后调用更快,避免循环。

我从来没有对array_map好过,因为我不太明白它是如何工作的,或者它是否是正确的路径。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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'
   )
);

使用查询

会更强大

答案 2 :(得分: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循环更快。

答案 3 :(得分: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
                        )

                )

        )

)