简体   繁体   中英

Build multidimensional array from an array in PHP

I would like to build a multidimensional array from an array. For example I would like

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

to become

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

or more simply

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

I'm trying to do this with a recursive function but i'm hitting memory limit so I'm clearly doing it wrong.

<?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;


}

Here's an approach with foreach and without recursion, which works:

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

[ Demo ]

Now your function... first, using $build[$array[0]] without defining it as an array first produces an E_NOTICE . Second, your function is going into infinite recursion because you are not actually modifying $array ( $temp isn't the same), so count($array) > 0 will be true for all of eternity.
And even if you were modifying $array , you couldn't use $array[0] anymore, because you unset that, and the indices don't just slide up. You would need array_shift for that.
After that, you pass $build and $temp to your function, which results in further because you now you assign $build to $temp , therefore creating another loop in your already-infinitely-recurring loop.

I was trying to fix all of the above in your code, but eventually realized that my code was now pretty much exactly the one from Pevara's answer , just with different variable names, so... that's that.

This function works recursively and does the trick:

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

In your code I would expect you see an error. You are talking to $build in your first iteration as if it where an array, while you have defaulted it to null .

It seems to be easy

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

return

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

Using a pointer, keep re-pointing it deeper. Your two output examples gave array() and null for the deepest value; this gives array() but if you want null , replace $p[$value] = array(); with $p[$value] = $test ? array() : null; $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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM