2

配列 1 のキーの値に基づいてマージしたい 2 つの配列があります。以下の例では、game_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 ループを簡単に実行して、この質問をまとめて回避することができました。現時点では、データベースに大量のゲーム モードを入力していませんが、常に追加し続けています。時間が経つにつれて、常に指数関数的に多くのループを実行すると、最終的にページの読み込み速度が遅くなります。

時間をかけてこのデータを memcache に配置し、ループを回避して将来の呼び出しを高速化しました。

array_map がどのように機能するか、または正しいルートであるかどうかがよくわからないため、私は 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;
    }
}

しかし、これが 2 つの 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 に答える