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

发布于 2024-09-02 05:58:24 字数 794 浏览 3 评论 0原文

当从 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 已存在(如果存在,则将该值推入其数组中)。

有没有内置的 php 函数可以帮助我解决这个问题?您知道如何构建这个吗?就其价值而言,我使用它在 WordPress 中构建了一个导航栏(可以包含类别、子类别、帖子......本质上是任何内容)。

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):

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).

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.

Take a look at the following illustration for further clarification:

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).

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黑白记忆 2024-09-09 05:58:24

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

这会在线性时间内构建树(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) {
        }
      }
    }
  }
}

最后 EDIT: unset $childrenTable 以清除引用标志。在实践中,您可能无论如何都想在函数内执行操作。

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)):

//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.

皇甫轩 2024-09-09 05:58:24

这个问题及其答案应该对您有帮助:将数据库结果转换为数组

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文