2012-05-23 3 views
2

J'ai 2 tableaux que je veux fusionner en fonction de la valeur d'une clé dans le tableau 1. Dans l'exemple ci-dessous, je veux que game_modes soit placé dans la liste de jeux en fonction d'une clé games_list.Tableaux de fusion PHP basés sur une clé de tableau spécifique

Tableau 1 qui est tiré d'une table pleine de jeux:

$games_list = array(
    0 => array(
    'id' => 23, 
    'name' => 'Call of Duty: Modern Warfare 3' 
    ), 
    2 => array(
    'id' => 1, 
    'name' => 'Call of Duty: Black Ops' 
    ) 
); 

Array 2 qui est tiré d'une table complète de modes de jeu:

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

Je voudrais que le résultat soit :

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

Infos supplémentaires, le site sur lequel je travaille actuellement contient 71 jeux dans sa base de données et chaque jeu pourrait avoir un nombre arbitraire de modes de jeu.

Maintenant, je pourrais facilement faire un tas de boucles pour éviter cette question et tous ensemble. En ce moment je n'ai pas la tonne de modes de jeu entré dans la base de données, mais je continue d'ajouter plus tout le temps. Avec le temps, faire plus de boucles exponentiellement tout le temps finira par faire tourner la vitesse de chargement de la page.

J'ai pris le temps de placer ces données dans memcache pour accélérer les prochains appels en évitant la boucle.

Je n'ai jamais été bon avec array_map car je ne comprends pas très bien comment cela fonctionne ou si c'est le bon chemin.

Répondre

3

Ne pensez-vous pas une solution de niveau de la requête serait mieux? Le long chemin serait:

// 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; 
     } 
     } 
    } 
} 

Catégorie de sortie: Résumé

$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'; 

Résultat:

id | name      | descriptions 
------------------------------------------------------------ 
    1 | Call of Duty: Black Ops | Capture the Flag, Domination 

Catégorie Sortie: Détail

$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'; 

Résultat:

id | name      | id | description 
----- --------------------------- ------- ------------------ 
    1 | Call of Duty: Black Ops | 1 | Capture the Flag 
    1 | Call of Duty: Black Ops | 2 | Domination 
+0

Je pensais à ce faire une façon de requête, mais j'aurais un tas d'entrées pour chaque jeu en fonction du nombre de modes de jeu. – Jayrox

+0

@Jayrox: Je crois toujours, la requête serait plus efficace. Pouvez-vous fournir des tableaux/champs pertinents? –

+0

table de jeux est juste (id, game_name) table de games_modes est (id, game_id, description) – Jayrox

0

Essayez ceci pour diminuer en boucle

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

Il sera plus facile si vous avez gamme $games_list comme celui-ci

$games_list = array(
    23 => array(
    'id' => 23, 
    'name' => 'Call of Duty: Modern Warfare 3' 
    ), 
    1 => array(
    'id' => 1, 
    'name' => 'Call of Duty: Black Ops' 
    ) 
); 

Et sera plus puissant en utilisant la requête

+0

sans faire une boucle for, est-il un moyen de faire une requête mysql faire les clés nommées en fonction de leur id, pour votre exemple? – Jayrox

+0

@Jayrox Je ne sais pas d'où vient votre tableau. Mais, s'ils viennent d'aller chercher, il y a un moyen. Pour votre information, mon exemple est pour votre situation de tableau actuel. Mais avec mon '$ games_list', vous n'avez pas besoin de $ cachearray dans mon code. –

+0

ils viennent d'une table mysql. jeux (id, nom) games_modes (id, game_id, description) – Jayrox

0

Si vous vouloir utiliser la carte tableau, ce code devrait être possible:

$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; 
    } 
} 

Mais je ne sais pas si c'est plus rapide que les deux pour les boucles.

0

essayez ceci:

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

Résultat:

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 
         ) 

       ) 

     ) 

) 
Questions connexes