2

我有 2 个数组,我想根据数组 1 中的键值进行合并。在下面的示例中,我希望根据 games_list 中的键 (id) 将 game_modes 放入 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

4 回答 4

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
于 2012-05-23T03:03:58.697 回答
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'
   )
);

并且通过使用查询将更强大

于 2012-05-23T03:20:26.020 回答
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 循环快。

于 2012-05-23T03:23:57.767 回答
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
                        )

                )

        )

)
于 2012-05-23T03:58:49.787 回答