2011-09-01 3 views
2

J'ai implémenté une traversée modifiée de l'arbre de précommande as explained here. Mon arbre est quelque chose comme ceci:Chemin d'accès dans une traversée modifiée de l'arbre de précommande

+-------+-----------+-----+-----+ 
| ref | name  | lft | rgt | 
+-------+-----------+-----+-----+ 
| NULL | base  | 1 | 8 | 
|  2 | basic  | 2 | 3 | 
| NULL | listener | 4 | 7 | 
|  1 | test  | 5 | 6 | 
+-------+-----------+-----+-----+ 

Tout est ok, mais maintenant j'ai essayé de mettre en œuvre une fonction de recherche de PHP basé sur un chemin, il est, quelque chose comme ceci:

$result = searchTree('base.listener.test'); 
// Now $result is an array with node {1, test} 

Cela signifie que searchTree renvoie un sous-arbre basé sur le chemin donné. Si le chemin n'existe pas, il retournera un tableau vide.

Mon implémentation actuelle est une fonction recyclée qui charge l'arbre dans un tableau PHP, puis il divise le chemin et parcourt le tableau. Cela semble être une implémentation non évolutive ... Une meilleure implémentation (peut-être en utilisant une requête mySQL?).

Ma mise en œuvre actuelle est comme ceci. D'abord, je reçois tout l'arbre (SELECT * FROM arbre) puis j'exécute cette fonction pour un tableau multidimensionnel de ces données:

function create_tree($results) { 
    $return = $results[0]; 
    array_shift($results); 

    if ($return['lft'] + 1 == $return['rgt']) 
     $return['leaf'] = true; 
    else { 
     foreach ($results as $key => $result) { 
      if ($result['lft'] > $return['rgt']) 
       break; 
      if ($rgt > $result['lft']) 
       continue; 
      $return['children'][] = create_tree(array_values($results)); 
      foreach ($results as $child_key => $child) { 
       if ($child['rgt'] < $result['rgt']) 
        unset($results[$child_key]); 
      } 
      $rgt = $result['rgt']; 
      unset($results[$key]); 
     } 
    } 

    unset($return['lft'],$return['rgt']); 
    return $return; 
} 

J'ai un tableau dans arbre $ variable et exécuter ce morceau de Code:

$t3 = $tree; 
$parts = explode('.', $path); 
while (isset($parts[0]) && count($parts) > 1 && isset($t3['children']) && $parts[0] == $t3['name']) { 
    array_shift($parts); 
    for ($i = 0; $i < count($tree['children']) && $tree['children'][$i]['name'] != $parts[0]; $i++); 
    $t3 = $tree['children'][$i]; 
} 

return isset($t3) && count($parts) == 1 && $parts[0] == $t3['name']? $t3['children'] : array(); 

la dernière ligne retourne le noeud pointé par le chemin de $ (ie « base.listener.test ») ou un tableau vide si ce chemin n'existe pas.

Répondre

0

Si je comprends ce que vous cherchez, vous voulez appeler:

$result = searchTree('test'); 

et obtenir une recherche dans la base de données pour les parents?

SELECT p.name 
    FROM tree c 
    INNER JOIN tree p ON p.lft < c.lft AND p.rgt > c.rgt 
    WHERE c.name = 'test' 
    ORDER BY p.lft; 
+0

Non, désolé. J'ai expliqué très mal ... (question éditée). searchTree() renvoie un tableau PHP multidimensionnel avec le sous-arbre correspondant. C'est à dire. Si vous demandez "base.listener.test", il retourne un tableau simple avec le noeud 'test'. Si quelqu'un demande 'test', il ne retournera aucun résultat car il n'y a pas d'élément racine appelé 'test'. Si quelqu'un demande 'base', il retournera un tableau avec tous les enfants de base: [basic, listener [test]] – Ivan

+0

Alors, cherchez-vous un meilleur moyen de remplir le tableau? Ou un moyen d'utiliser l'arbre sans créer le tableau? –

+0

Une meilleure façon de peupler le tableau, parce que je crois que ma méthode n'est pas très évolutive (maintenant j'ai 100 items dans l'arbre, mais je prévois en avoir environ 10.000) – Ivan

Questions connexes