2010-07-16 35 views
7

Tengo una matriz con datos de árbol (por id principal). Quiero convertirlo a una matriz multidimensional. ¿Cuál es la mejor manera de lograr eso? ¿Hay alguna función corta para eso?Convertir matriz plana a la multidimensional

array Fuente:

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

Algunos padres no se encuentran en la matriz de origen. Me gustaría que los elementos con el padre faltante sean raíz. Matriz de resultados:

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

Actualización: se eliminaron los corchetes.

+1

Esa primera ya es una matriz multidimensional. Multidimensional simplemente significa matrices dentro de matrices. – animuson

+0

¿Estás usando pastel? – Young

+0

uh esto no es PHP válido ... ¿qué [0] => matriz (... o ['Menú'] => matriz (... significa? Así que estoy bastante atascado sin entender la forma de su entrada datos. –

Respuesta

16

No creo que hay una función incorporada en PHP que hace esto.

He probado el código siguiente y parece que funciona para preparar la matriz anidada de la manera que usted describe:

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

escribí un algoritmo similar en una clase PHP que escribí para mi presentación Hierarchical Models in SQL and PHP, pero estaba usando objetos en lugar de matrices simples.

+0

¡Eres fantástico! ¡Gracias por la solución de trabajo y la respuesta rápida sush! La matriz fuente es el resultado de la consulta de la base de datos. – bancer

+1

Tenga en cuenta que este algoritmo funciona solo si los padres aparecen en el conjunto de resultados db antes de que aparezcan sus hijos. –

+0

Nice code.Take +1 – Oyeme

0

Escribí esta variante considerando que root_id es 0 o que falta. No importa niños después de padres en DB ($ fuente) o no.

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

Las claves de matriz de resultados son identificadores apropiados. ¡Disfrutar!

0

que estaba buscando un ejemplo de cómo hacer esto, con categorías. Este ejemplo asume que los padres siempre tendrán un id principal de '0'. El ejemplo es usar ZF2.

Sin referencias ni recursividad. El truco está en el resultado, busca el índice [0] y para los hijos, especifica el parent_id como el índice.

$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> 
Cuestiones relacionadas