基于特定数组键的PHP合并数组

基于特定数组键的PHP合并数组,php,arrays,Php,Arrays,我有两个数组,我想根据数组1中键的值合并它们。在下面的示例中,我希望根据games_列表中的键(id)将game_模式放入games_列表中 从满是游戏的桌子上拉出的阵列1: $games_list = array( 0 => array( 'id' => 23, 'name' => 'Call of Duty: Modern Warfare 3' ), 2 => array( 'id' => 1, 'name' =&

我有两个数组,我想根据数组1中键的值合并它们。在下面的示例中,我希望根据games_列表中的键(id)将game_模式放入games_列表中

从满是游戏的桌子上拉出的阵列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:  $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
  id |  name                     |  id   |  description
----- --------------------------- ------- ------------------
  1  |  Call of Duty: Black Ops  |   1   |  Capture the Flag
  1  |  Call of Duty: Black Ops  |   2   |  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                     |  descriptions
------------------------------------------------------------
  1  |  Call of Duty: Black Ops  |  Capture the Flag, Domination
  id |  name                     |  id   |  description
----- --------------------------- ------- ------------------
  1  |  Call of Duty: Black Ops  |   1   |  Capture the Flag
  1  |  Call of Duty: Black Ops  |   2   |  Domination

尝试此方法以减少循环

$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\u 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'
   )
);

如果您想使用数组映射,则可以使用以下代码:

$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循环快。

试试这个:

$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
                        )

                )

        )

)

我想用查询的方式来做,但是我会根据游戏模式的数量为每一个游戏设置一组条目。@Jayrox:我仍然相信,查询会是一种更有效的方式。你能提供相关的表格/字段吗?游戏表格只是(id,游戏名称)游戏模式表格是(id,游戏id,描述)相应地更新了我的帖子。我认为这是最有效的解决方案。好的,运行查询,结果如您所述。这可能适合我的需要。我将尝试并选择此答案。如果不执行for循环,是否有方法进行mysql查询,例如,根据密钥的id命名密钥?@Jayrox我不知道您的数组来自何处。但是,如果他们是从抓取所以有一个办法。仅供参考,我的示例适用于您当前的阵列情况。但是使用我的
$games\u列表
,那么我的代码中就不需要
$cachearray
。它们来自mysql表。games(id,name)games_modes(id,games_id,description)@Jayrox在你的代码中有类似于
mysql_fetch_array
的东西吗?我使用的是PDO,它在数组中给出结果