2015-05-15 6 views
6

Vorrei creare un array multidimensionale da un array. Per esempio vorreiCreare array multidimensionale da un array in PHP

$test = array (
0 => 'Tree', 
1 => 'Trunk', 
2 => 'Branch', 
3 => 'Limb', 
4 => 'Apple', 
5 => 'Seed' 
); 

per diventare

$test = 
array (
    'Tree' => array (
     'Trunk' => array (
      'Branch' => array (
       'Limb' => array (
        'Apple' => array (
         'Seed' => array() 
        ) 
       ) 
      ) 
     ) 
    ) 
); 

o più semplicemente

$result[Tree][Trunk][Branch][Limb][Apple][Seed] = null; 

che sto cercando di fare questo con una funzione ricorsiva ma sto colpendo limite di memoria in modo Sto chiaramente sbagliando.

<?php 
$test = array (
0 => 'Tree', 
1 => 'Trunk', 
2 => 'Branch', 
3 => 'Limb', 
4 => 'Apple', 
5 => 'Seed' 
); 



print_r($test); 





print "results of function"; 

print_r(buildArray($test)); 



function buildArray (&$array, &$build = null) 
{ 
    if (count($array) > 0) 
    { 

     //create an array, pass the array to itself removing the first value 



     $temp = array_values($array); 
     unset ($temp[0]);   
     $build[$array[0]] = $temp; 


     buildArray($build,$temp); 



     return $build; 
    } 

    return $build; 


} 
+0

Questo è un buon esempio del perché ricorsione non è necessariamente una buona idea la maggior parte del tempo.In genere è molto semplice svolgersi in ricorsione e, in tal modo, si ottiene un codice in genere più veloce, meno ingombrante e più facile da capire. –

risposta

2

Questa funzione opera in modo ricorsivo e fa il trucco:

function buildArray($from, $to = []) { 
    if (empty($from)) { return null; } 
    $to[array_shift($from)] = buildArray($from, $to); 
    return $to; 
} 

Nel codice che ci si aspetterebbe di vedere un errore. Stai parlando con $build nella tua prima iterazione come se fosse in un array, mentre lo hai predefinito su null.

8

Ecco un approccio con foreach e senza ricorsione, che funziona:

function buildArray($array) 
{ 
    $new = array(); 
    $current = &$new; 
    foreach($array as $key => $value) 
    { 
     $current[$value] = array(); 
     $current = &$current[$value]; 
    } 
    return $new; 
} 

[Demo]

Ora la funzione ... prima, utilizzando $build[$array[0]] senza definirlo come un array prima produce un E_NOTICE. In secondo luogo, la funzione sta andando in ricorsione infinita perché in realtà non stai modificando $array ($temp non è la stessa), quindi count($array) > 0 sarà vero per tutta l'eternità.
E anche se stavi modificando $array, non potresti più utilizzare $array[0] perché non lo hai impostato e gli indici non si limitano a scorrere. Avresti bisogno di array_shift per quello.
Dopo di che, si passa $build e $temp alla funzione, che si traduce in più perché ora si assegna $build a $temp, creando così un altro ciclo nel vostro ciclo già infinitamente ricorrente.

Stavo cercando di correggere tutto quanto sopra nel tuo codice, ma alla fine ho capito che il mio codice ora era esattamente quello di Pevara's answer, solo con nomi di variabili differenti, quindi ... ecco.

0

Utilizzando un puntatore, continua a puntarlo nuovamente più a fondo. I tuoi due esempi di output hanno dato array() e null per il valore più profondo; questo dà array() ma se si vuole null, sostituire $p[$value] = array(); con $p[$value] = $test ? array() : null;

$test = array(
    'Tree', 
    'Trunk', 
    'Branch', 
    'Limb', 
    'Apple', 
    'Seed' 
); 

$output = array(); 
$p = &$output; 
while ($test) { 
    $value = array_shift($test); 
    $p[$value] = array(); 
    $p = &$p[$value]; 
} 
print_r($output); 
2

sembra essere facile

$res = array(); 
$i = count($test); 
while ($i) 
    $res = array($test[--$i] => $res); 
var_export($res); 

ritorno

array ('Tree' => array ('Trunk' => array ('Branch' => array ('Limb' => array ('Apple' => array ('Seed' => array (),),),),),),) 
+0

Soluzione interessante per non utilizzare i puntatori. Tuttavia non è il più efficiente. –

+0

@JohnCartwright Perché è meno efficiente delle funzioni di chiamata? – splash58

+0

Non ha nulla a che fare con le funzioni. Ha a che fare con la creazione di copie vs riferimenti. –