2

我有一个看起来像这样的数组

array(
    1 => array(
        'id'     => 1,
        'name'   => 'first',
        'parent' => null
    ),
    2 => array(
        'id'     => 2,
        'name'   => 'second',
        'parent' => null
    ),
    3 => array(
        'id'     => 3,
        'name'   => 'third',
        'parent' => 1
    ),
    4 => array(
        'id'     => 4,
        'name'   => 'fourth',
        'parent' => 3
    ),
    5 => array(
        'id'     => 5,
        'name'   => 'fifth',
        'parent' => 1
    ),        
);

但我想将任何“子”项移动到数组下的“子”键。所以,我想结束

array(
    1 => array(
        'id'       => 1,
        'name'     => 'first',
        'parent'   => null,
        'children' => array(
            3 => array(
                'id'       => 3,
                'name'     => 'third',
                'parent'   => 1,
                'children' => array(
                    4 => array(
                        'id'       => 4,
                        'name'     => 'fourth',
                        'parent'   => 3,
                        'children' => array()
                    ),
                )
            ),
            5 => array(
                'id'       => 5,
                'name'     => 'fifth',
                'parent'   => 1,
                'children' => array()
            )
        )
    ),
    2 => array(
        'id'       => 2,
        'name'     => 'second',
        'parent'   => null,
        'children' => array()
    )
);

但老实说,我完全不知道从哪里开始。

我在想也许循环遍历数组中的每个项目,然后随着我一起构建新数组$new_array[$current['parent']]['children'][$current['id']] = $current;

但是,一旦我遇到嵌套项目,我就会遇到问题。

我可以构建一个函数,该函数采用当前数组和整个数组并递归地向上移动树以找到所有父级,从而找到整个路径,但如果其中一个父级尚未创建,我会再次遇到问题。

我能想到的唯一选择是构建一个不同级别的父母的数组映射并递归地循环并以这种方式获取所有元素,但这似乎有点低效?

任何人都可以提出解决方案吗?

4

2 回答 2

3

你对 foreach 循环有正确的想法。但是,您想要做的事情需要引用的“魔力”。

foreach($oldArray as $key => &$item) {
    if($item["parent"] == null) $newArray[$key] = &$item;
    else $oldArray[$item["parent"]]["children"][$key] = &$item;
}

unset($item);

这将输出'$oldArray'

Array
(
[1] => Array
    (
        [id] => 1
        [name] => first
        [parent] => 
        [children] => Array
            (
                [3] => Array
                    (
                        [id] => 3
                        [name] => third
                        [parent] => 1
                        [children] => Array
                            (
                                [4] => Array
                                    (
                                        [id] => 4
                                        [name] => fourth
                                        [parent] => 3
                                    )

                            )

                    )

                [5] => Array
                    (
                        [id] => 5
                        [name] => fifth
                        [parent] => 1
                    )

            )

    )

[2] => Array
    (
        [id] => 2
        [name] => second
        [parent] => 
    )

[3] => Array
    (
        [id] => 3
        [name] => third
        [parent] => 1
        [children] => Array
            (
                [4] => Array
                    (
                        [id] => 4
                        [name] => fourth
                        [parent] => 3
                    )

            )

    )

[4] => Array
    (
        [id] => 4
        [name] => fourth
        [parent] => 3
    )

[5] => Array
    (
        [id] => 5
        [name] => fifth
        [parent] => 1
    )

)

对于 newArray (“纯化”版本)

Array
(
[1] => Array
    (
        [id] => 1
        [name] => first
        [parent] => 
        [children] => Array
            (
                [3] => Array
                    (
                        [id] => 3
                        [name] => third
                        [parent] => 1
                        [children] => Array
                            (
                                [4] => Array
                                    (
                                        [id] => 4
                                        [name] => fourth
                                        [parent] => 3
                                    )

                            )

                    )

                [5] => Array
                    (
                        [id] => 5
                        [name] => fifth
                        [parent] => 1
                    )

            )

    )

[2] => Array
    (
        [id] => 2
        [name] => second
        [parent] => 
    )

)

现在,为什么会这样:通过将 &item 放入 foreach 循环,我们使用对项目的引用,而不是副本。这意味着,无论我们对该项目进行什么更改,我们也会在相应的数组元素处进行更改。

通过将 &$item 传递给 $newArray[$key] 或 children 数组,我们将引用传递……所以无论我们对“原始对象”(即 [3])做什么,我们也会对所有参考。

unset($item) 是必要的,因为它删除了 $item 的最后一个实例和变量之间的绑定。否则,只要我们再次更改 $item 变量,我们也会更改最后一个变量。在这个脚本中不是完全必要的,但仍然是一个需要记住的好习惯。

于 2012-08-21T05:46:38.893 回答
0

您可以将它们从数组转换为对象。这很容易做到,你几乎已经有了一个对象结构。

__construct()不同之处在于您可以在每个对象中设置一个函数,将其ID编号作为参数传递,并在__construct()函数内部查看子数组的主数组并将它们添加进去。当它添加一个新的子项时,它再次触发__construct()这个孩子中的函数,它将再次在数组中搜索它自己的孩子。

你很可能最终得到一个几乎没有工作的美妙物体。如果你希望它们在最后作为一个数组,你可以有一个函数将整个 heirachy 作为一个数组返回 - 但无论如何对象对你来说不是更好吗?

于 2012-08-21T05:47:53.997 回答