2010-07-16 12 views
7

J'ai un tableau avec des données d'arbre (par parent ID). Je veux le convertir en tableau multidimensionnel. Quel est le meilleur moyen d'y parvenir? Y at-il une fonction courte pour cela?Convertir un tableau à plat en plusieurs dimensions

tableau Source:

$source = array(
    '0' => array(
      'Menu' => array(
        'id' => 45 
        'name' => 'Home' 
        'parent_id' => 1 
      ) 
    ) 
    '1' => array(
      'Menu' => array(
        'id' => 47 
        'name' => 'Get started' 
        'parent_id' => 1 
      ) 
    ) 
    '2' => array(
      'Menu' => array(
        'id' => 72 
        'name' => 'Attributes' 
        'parent_id' => 71 
      ) 
    ) 
    '3' => array(
      'Menu' => array(
        'id' => 73 
        'name' => 'Headings' 
        'parent_id' => 71 
      ) 
    ) 
    '4' => array(
      'Menu' => array(
        'id' => 75 
        'name' => 'Links' 
        'parent_id' => 71 
      ) 
    ) 
    '5' => array(
      'Menu' => array(
        'id' => 59 
        'name' => 'Images' 
        'parent_id' => 75 
      ) 
    ) 
    '6' => array(
      'Menu' => array(
        'id' => 65 
        'name' => 'Lists' 
        'parent_id' => 75 
      ) 
    ) 
); 

Certains parents sont absents du tableau source. Je voudrais que les éléments avec parent absent soient root. Tableau de résultats:

$result = array(
    '0' => array(
      'Menu' => array(
        'id' => 45 
        'name' => 'Home' 
        'parent_id' => 1 
      ) 
      'Children' => array() 
    ) 
    '1' => array(
      'Menu' => array(
        'id' => 47 
        'name' => 'Get started' 
        'parent_id' => 1 
      ) 
      'Children' => array() 
    ) 
    '2' => array(
      'Menu' => array(
        'id' => 72 
        'name' => 'Attributes' 
        'parent_id' => 71 
      ) 
      'Children' => array() 
    ) 
    '3' => array(
      'Menu' => array(
        'id' => 73 
        'name' => 'Headings' 
        'parent_id' => 71 
      ) 
      'Children' => array() 
    ) 
    '4' => array(
      'Menu' => array(
        'id' => 75 
        'name' => 'Links' 
        'parent_id' => 71 
      ) 
      'Children' => array(
        '0' => array(
         'Menu' => array(
          'id' => 59 
          'name' => 'Images' 
          'parent_id' => 75 
         ) 
         'Children' => array() 
        ) 
        '1' => array(
         'Menu' => array(
          'id' => 65 
          'name' => 'Lists' 
          'parent_id' => 75 
         ) 
         'Children' => array() 
        ) 
      ) 
    ) 
); 

Mise à jour: crochets supprimés.

+1

Ce premier est déjà un tableau multidimensionnel. Multidimensionnel signifie simplement des tableaux à l'intérieur de tableaux. – animuson

+0

utilisez-vous un gâteau? – Young

+0

euh ce n'est pas valide PHP .. qu'est-ce que [0] => tableau (... ou ['Menu'] => tableau (... signifie? Donc je suis plutôt bloqué ne pas comprendre la forme de votre entrée . Les données –

Répondre

16

Je ne pense pas qu'il existe une fonction intégrée dans PHP qui fait cela.

J'ai essayé le code suivant, et il semble fonctionner pour préparer le tableau imbriqué la façon dont vous décrivez:

$nodes = array(); 
$tree = array(); 
foreach ($source as &$node) { 
    $node["Children"] = array(); 
    $id = $node["Menu"]["id"]; 
    $parent_id = $node["Menu"]["parent_id"]; 
    $nodes[$id] =& $node; 
    if (array_key_exists($parent_id, $nodes)) { 
    $nodes[$parent_id]["Children"][] =& $node; 
    } else { 
    $tree[] =& $node; 
    } 
} 

var_dump($tree); 

j'ai écrit un algorithme similaire dans une classe PHP j'ai écrit pour ma présentation Hierarchical Models in SQL and PHP, mais je utilisait des objets au lieu de tableaux simples.

+0

Vous êtes fantastique! Merci pour la solution de travail et sush réponse rapide! Le tableau source est le résultat de la requête de base de données. – bancer

+1

Notez que cet algorithme ne fonctionne que si les parents apparaissent dans le jeu de résultats db avant que leurs enfants apparaissent. –

+0

Nice code.Prendre +1 – Oyeme

0

J'ai écrit cette variante en considérant root parent_id est 0 ou manquant. Peu importe les enfants après les parents dans DB ($ source) ou non.

$source_by_id = array(); 
foreach ($source as &$row){ 
    $source_by_id[$row['id']] = &$row; 
} 
foreach ($source_by_id as $id => &$row){ 
    $source_by_id[ intval($row['parent_id']) ]['children'][$id] = &$row; 
} 
// remove cycling itself 
unset($source_by_id[0]['children'][0]); 

$result = $source_by_id[0]['children']; 

Les clés de tableau de résultats sont des identifiants appropriés. Prendre plaisir!

0

Je cherchais un exemple de la façon de le faire, avec des catégories. Cet exemple suppose que les parents auront toujours un identifiant parent de '0'. L'exemple utilise ZF2.

Aucune référence, ou récursion. L'astuce est dans la sortie, vous recherchez l'index [0], et pour les enfants, vous spécifiez le parent_id comme index.

$categoryLookup = $this->getCategoryLookup($associateById=true); 

if ($assignedCategories) {   
    $categoryHeirarchy = array(); 
    foreach($assignedCategories as $assignedCategory) { 
     $child = $categoryLookup[$assignedCategory->category_id]; 
     $parent = $categoryLookup[$child->parent_id];    
     $categoryHeirarchy[$child->parent_id][] = $categoryLookup[$child->category_id]; 
     $categoryHeirarchy[$parent->parent_id][$parent->category_id] = $categoryLookup[$parent->category_id]; 
    }   

    return $categoryHeirarchy; 
} 


<h3>Categories</h3> 
<dl class="dl-horizontal"> 
    <?php foreach($this->categoryHeirarchy[0] as $parent): ?> 
     <dt><?php echo $this->escapeHtml($parent->name); ?></dt> 
     <?php foreach($this->categoryHeirarchy[$parent->category_id] as $child): ?> 
      <dd><?php echo $this->escapeHtml($child->name); ?></dd> 
     <?php endforeach; ?> 
    <?php endforeach; ?>      
</dl>