2010-11-10 4 views
0

J'ai une structure arborescente composée de tableaux associatifs imbriqués. J'ai un ensemble de chemins que je veux ajouter à l'arbre, où chaque élément du chemin est le nom d'un nœud. Le code ci-dessous devrait créer le nœud "2" sous "a" (ce qu'il fait) et créer les nœuds "i", "ii" et "iii" sous "2". Pour une raison quelconque, le premier nœud créé sous "2" est perdu. Il imprimera qu'il est en cours de création, mais print_r affiche uniquement "ii" et "iii".PHP - Tree of Array Les références, d'abord ajoutées à un nouveau tableau sont perdues

$tree = array(
    name => 'root', 
    children => array(
     array(
      name => 'a', 
      children => array(), 
     ), 
    ), 
); 


$paths = array(
    array('a','2','i'), 
    array('a','2','ii'), 
    array('a','2','iii'), 
); 


foreach ($paths as $path) { 
    $node =& $tree; 
    $found = true; 
    while($found && count($path) > 0) { 
     $name = $path[0]; 
     $found = false; 
     echo "looking for $name\n"; 
     foreach ($node['children'] as &$child) { 
      if($name == $child['name']) { 
       echo "found $name\n"; 
       $node =& $child; 
       $found = true; 
       break; 
      } 
     } 
     if($found) { 
      array_shift($path); 
     } 
    } 
    if(!$found) { 
     echo "didn't find $name\n"; 
     while(count($path) > 0) { 
      $name = array_shift($path); 
      echo "creating $name in ".$node['name']."\n"; 
      $newNode = array(
       'name' => $name, 
       'children' => array(), 
      ); 
      $node['children'][] = $newNode; 
      $node =& $newNode; 
     } 
    } 
} 

print_r($tree); 

Je soupçonne que le problème a à voir avec la façon dont j'initialisant les enfants de « 2 », car il sera créé dans la boucle, mais je ne sais pas ce que je fais mal.

EDIT: Je compris comment le faire fonctionner ... Changer cette dernière boucle intérieure de:

 $newNode = array(
      'name' => $name, 
      'children' => array(), 
     ); 
     $node['children'][] = $newNode; 
     $node =& $newNode; 

à

 $children =& $node['children']; 
     $children[] = array(
      'name' => $name, 
      'children' => array() 
     ); 
     $node =& $children[count($children)-1]; 

semble le faire, mais je ne suis pas Bien sûr pourquoi. Une bonne explication est due.

Répondre

0

Toutes ces références nuisent à mon cerveau, mais il est une erreur évidente que je peux voir dans:

$node['children'][] = $newNode; 
$node =& $newNode; 

La deuxième ligne avec une $node écrase référence à $newNode, de sorte que la première ligne est inutilisée.

Dans votre nouvelle version, vous créez le tableau $children, en effectuant la manipulation, puis en définissant la référence $node, ce qui explique pourquoi cela fonctionne.

+0

Pouvez-vous expliquer un peu plus? $ node doit être une référence au nœud parent, j'essaie donc d'y ajouter $ newNode, puis de descendre au nouveau nœud pour l'itération suivante. Que voulez-vous dire quand vous dites que "la première ligne est inutilisée?" L'ajout d'un enfant ne fait rien? – noah

Questions connexes