【问题标题】:Build multidimensional array from an array in PHP从 PHP 中的数组构建多维数组
【发布时间】:2023-03-21 11:30:02
【问题描述】:

我想从一个数组构建一个多维数组。比如我想

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

成为

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

或者更简单

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

我正在尝试使用递归函数来执行此操作,但我遇到了内存限制,所以我显然做错了。

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


}

【问题讨论】:

  • 这是一个很好的例子,说明为什么递归在大多数情况下不一定是个好主意。展开递归通常非常容易,这样做通常会更快、占用更少、更容易理解代码。

标签: php arrays function recursion multidimensional-array


【解决方案1】:

这是一种使用 foreach 且不使用递归的方法,该方法有效:

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

[Demo]

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

我试图在您的代码中修复上述所有问题,但最终意识到我的代码现在几乎与 Pevara's answer 中的代码完全相同,只是变量名称不同,所以......就是这样。

【讨论】:

    【解决方案2】:

    使用指针,不断地重新指向它。您的两个输出示例给出了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);
    

    【讨论】:

      【解决方案3】:

      这个函数递归地工作并且可以解决问题:

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

      在您的代码中,我希望您会看到一个错误。您在第一次迭代中与 $build 交谈,就好像它在数组中一样,而您已将其默认为 null

      【讨论】:

        【解决方案4】:

        好像很简单

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

        返回

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

        【讨论】:

        • 不使用指针的有趣解决方案。虽然不是最有效的。
        • @JohnCartwright 为什么比调用函数效率低?
        • 与函数无关。这与创建副本与参考有关。
        • @JohnCartwright 你写的Not the most efficient though.我的代码有什么不生效的?只是想知道
        • 我没听懂你最后的评论。
        猜你喜欢
        • 2013-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 2014-02-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-17
        相关资源
        最近更新 更多