PHP数组——如何将一维数组嵌套到多维数组中?

时间:2022-03-27 21:26:27

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列和一个父列表示层次关系的表),我将结果映射到如下所示的枚举数组中(本例中的数字是任意的):

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. Regardless, any ID's children will be pushed into their parent's array.

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

Take a look at the following illustration for further clarification:

为了进一步说明,请看下面的插图:

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

alt文本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? 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).

是否有一个内置的php函数可以帮助我实现这一点?你知道怎么做这个吗?值得注意的是,我用它在wordpress中构建了一个导航条(它可以包含类别、子类别、文章……)基本上任何东西)。

2 个解决方案

#1


1  

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_exist进行哈希表查找,平均为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. In practice, you will probably want to do the operation inside a function anyway.

编辑:最后未设置$childrenTable以清除参考标志。实际上,您可能希望在函数中执行操作。

#2


1  

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演示文稿,特别是关于闭包表的主题。

#1


1  

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_exist进行哈希表查找,平均为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. In practice, you will probably want to do the operation inside a function anyway.

编辑:最后未设置$childrenTable以清除参考标志。实际上,您可能希望在函数中执行操作。

#2


1  

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演示文稿,特别是关于闭包表的主题。