Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;


}
like image 909
Kven Avatar asked May 15 '15 18:05

Kven


2 Answers

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.

like image 59
Siguza Avatar answered Sep 22 '22 01:09

Siguza


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.

like image 26
Pevara Avatar answered Sep 22 '22 01:09

Pevara