孩子排序数组?

时间:2012-08-21 05:36:45

标签: php arrays recursion multidimensional-array

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

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
    ),        
);

但我想将任何“子”项移动到数组下的“children”键。 所以,我想最终得到

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;时构建新数组

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

我可以构建一个接受当前数组的函数,整个数组以递归方式向上移动树来查找所有父节点,从而找到整个路径,但如果父节点之一尚未创建,我会再次遇到问题爱好。

我能想到的唯一选择是构建一个不同级别的父级的数组映射,并以递归的方式循环,然后抓住所有元素,但这看起来有点低效?

有人可以建议解决方案吗?

2 个答案:

答案 0 :(得分: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]或子数组,我们传递引用...所以无论我们对'原始对象'做什么(即[3]),我们也做所有参考。

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

答案 1 :(得分:0)

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

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

你最终可能会得到一个很好的物体,旁边没有工作。如果你想把它们作为一个数组放在最后,那么你可以使用一个函数将整个heirachy作为一个数组返回 - 但是无论如何你的对象不会更好吗?