【问题标题】:PHP arrays - How to 1-dimensional array into nested multidimensional array?PHP 数组 - 如何将一维数组转换为嵌套多维数组?
【发布时间】:2010-05-23 17:19:53
【问题描述】:

当从 MySQL 检索层次结构时(表有一个 ID 列和一个 PARENT 列表示层次关系),我将结果映射到一个枚举数组中,如下所示(对于这个例子,数字是任意的):

Array ( [3] => Array ( [7] => Array () ), [7] => Array ( [8] => Array () ) )

注意 3 是 7 的父级,而 7 是 8 的父级(这可以一直持续下去;任何父级都可以有多个子级)。

我想把这个数组收缩成一个嵌套的多维数组,如下所示:

Array ( [3] => Array ( [7] => Array ( [8] => Array () ) ) )

也就是说,每个 NEW id 都会自动分配一个空数组。无论如何,任何 ID 的子代都会被推入其父代的数组中。

请看下面的插图以获得进一步的说明:

alt text http://img263.imageshack.us/img263/4986/array.gif

这可能会导致复杂的递归操作,因为我总是必须检查具有任何特定 ID 的父级是否已经存在(如果存在,则将值推入其数组中)。 p>

有没有内置的 php 函数可以帮助我解决这个问题?您对如何构建这个有任何想法吗?值得我用它在 wordpress 中构建一个导航栏(它可以包含类别、子类别、帖子......基本上任何东西)。

【问题讨论】:

    标签: php arrays map recursion


    【解决方案1】:

    这个想法是你保留一个辅助数组,其中包含你找到的所有节点(父节点和子节点)。该数组的值是支持您的结果的引用。

    这会在线性时间内构建树(array_key_exists 进行哈希表查找,平均为 O(1)):

    //table contains (id, parent)
    $orig = array(
        11 => 8,
        7 => 3,
        8 => 7,
        99 => 8,
        16 => 8,
    );
    
    $childrenTable = array();
    $result = array();
    
    foreach ($orig as $n => $p) {
        //parent was not seen before, put on root
        if (!array_key_exists($p, $childrenTable)) {
            $childrenTable[$p] = array();
            $result[$p] = &$childrenTable[$p];
        }
        //child was not seen before
        if (!array_key_exists($n, $childrenTable)) {
            $childrenTable[$n] = array();
        }
    
        //root node has a parent after all, relocate
        if (array_key_exists($n, $result)) {
            unset($result[$n]);
        }
    
        $childrenTable[$p][$n] = &$childrenTable[$n];
    }
    unset($childrenTable);
    
    var_dump($result);
    

    给予

    array(1) {
      [3]=>
      array(1) {
        [7]=>
        array(1) {
          [8]=>
          array(3) {
            [11]=>
            array(0) {
            }
            [99]=>
            array(0) {
            }
            [16]=>
            array(0) {
            }
          }
        }
      }
    }
    

    编辑:最后取消设置 $childrenTable 以清除引用标志。在实践中,您可能无论如何都希望在函数内部进行操作。

    【讨论】:

    • 感谢您的努力,我现在正在尝试看看它是否真的是防弹的。
    【解决方案2】:

    这个问题及其答案应该对您有所帮助:turn database result into array

    请务必阅读@Bill Karwin 的 PDF 演示文稿,特别是有关 Closure 表的主题。

    【讨论】:

      猜你喜欢
      • 2016-12-16
      • 2011-08-24
      • 2019-04-03
      • 1970-01-01
      • 2016-09-28
      • 1970-01-01
      • 2023-03-26
      • 2019-06-29
      相关资源
      最近更新 更多