在PHP中从数组构建多维数组

时间:2022-10-12 10:49:40

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;


}

4 个解决方案

#1


2  

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.

在您的代码中,我希望您看到错误。你在第一次迭代中讨论$ build,就好像它是一个数组,而你将它默认为null。

#2


8  

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

这是一个foreach和没有递归的方法,它有效:

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.

现在你的函数......首先,使用$ build [$ array [0]]而不将其定义为数组首先产生一个E_NOTICE。其次,你的函数进入无限递归,因为你实际上并没有修改$ array($ temp不一样),所以count($ array)> 0将永远为真。即使你正在修改$ array,你也不能再使用$ array [0],因为你取消了它,并且索引不会只是向上滑动。你需要array_shift。之后,您将$ build和$ temp传递给您的函数,这会导致更进一步,因为您现在将$ build分配给$ temp,从而在已经无限循环的循环中创建另一个循环。

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.

我试图在你的代码中修复上述所有内容,但最终意识到我的代码现在几乎完全是Pevara的答案,只是使用不同的变量名称,所以......就是这样。

#3


2  

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 ( ), ), ), ), ), ), )

#4


0  

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;

使用指针,继续重新指向它。您的两个输出示例为最深的值提供了array()和null;这给了array()但是如果你想要null,则替换$ p [$ value] = array();用$ 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);

#1


2  

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.

在您的代码中,我希望您看到错误。你在第一次迭代中讨论$ build,就好像它是一个数组,而你将它默认为null。

#2


8  

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

这是一个foreach和没有递归的方法,它有效:

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.

现在你的函数......首先,使用$ build [$ array [0]]而不将其定义为数组首先产生一个E_NOTICE。其次,你的函数进入无限递归,因为你实际上并没有修改$ array($ temp不一样),所以count($ array)> 0将永远为真。即使你正在修改$ array,你也不能再使用$ array [0],因为你取消了它,并且索引不会只是向上滑动。你需要array_shift。之后,您将$ build和$ temp传递给您的函数,这会导致更进一步,因为您现在将$ build分配给$ temp,从而在已经无限循环的循环中创建另一个循环。

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.

我试图在你的代码中修复上述所有内容,但最终意识到我的代码现在几乎完全是Pevara的答案,只是使用不同的变量名称,所以......就是这样。

#3


2  

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 ( ), ), ), ), ), ), )

#4


0  

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;

使用指针,继续重新指向它。您的两个输出示例为最深的值提供了array()和null;这给了array()但是如果你想要null,则替换$ p [$ value] = array();用$ 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);