简体   繁体   English

PHP数组 - 如何将1维数组转换为嵌套的多维数组?

[英]PHP arrays - How to 1-dimensional array into nested multidimensional array?

When retrieving a hierarchical structure from MySQL (table with one ID column and one PARENT column signifying the hierarchical relationships), I map the result into an enumerated array as follows (for this example the numbers are arbitrary): 从MySQL(具有一个ID列和一个PARENT列表示层次关系的表)检索层次结构时,我将结果映射到枚举数组中,如下所示(对于此示例,数字是任意的):

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

Notice 3 is the parent of 7, and 7 is the parent of 8 (this could go on and on; and any parent could have multiple children). 通知3是7的父级,7是8的父级(这可以继续;并且任何父级可以有多个子级)。

I wanted to shrink this array into a nested multidimensional array as follows: 我想将此数组缩小为嵌套的多维数组,如下所示:

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

That is, each NEW id is automatically assigned an empty array. 也就是说, 每个NEW id都会自动分配一个空数组。 Regardless, any ID's children will be pushed into their parent's array. 无论如何,任何ID的孩子都会被推入他们父母的阵列中。

Take a look at the following illustration for further clarification: 请查看下图以进一步说明:

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

This will probably result in a complicated recursive operation, since I always have to check whether a parent with any certain ID already exists (and if so, push the value into its array). 这可能会导致复杂的递归操作,因为我总是必须检查具有任何特定ID的父级是否已经存在 (如果是,则将值推入其数组中)。

Is there a built-in php function that can assist me with this? 是否有内置的PHP功能可以帮助我这个? Do you have any idea as to how to go about constructing this? 你对如何构建这个有任何想法吗? For what it's worth I'm using this to built a navigation bar in wordpress (which can contain categories, subcategories, posts... essentially anything). 对于它的价值,我使用它在wordpress中构建一个导航栏(可以包含类别,子类别,帖子......基本上任何东西)。

This question and it's answers should be helpful to you: turn database result into array . 这个问题及其答案应该对您有所帮助: 将数据库结果转换为数组

Be sure to read the PDF presentation by @Bill Karwin, specifically the topics regarding the Closure table. 请务必阅读@Bill Karwin的PDF演示文稿,特别是关于Closure表的主题。

The idea is that you keep an auxiliary array with all the nodes (parent and child) you find. 我们的想法是保留一个辅助数组,其中包含您找到的所有节点(父节点和子节点)。 The values of this arrays are references that back your result. 此数组的值是支持结果的引用。

This builds the tree in linear time (array_key_exists does a hash table lookup, which is on average O(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);

gives

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

EDIT: unset $childrenTable in the end to clear reference flags. 编辑:unset $childrenTable到底清除引用标志。 In practice, you will probably want to do the operation inside a function anyway. 实际上,您可能希望在函数内部进行操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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