【问题标题】:PHP Traversing Function to turn single array into nested array with children - based on parent idPHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID
【发布时间】:2010-01-19 14:42:41
【问题描述】:

我有一个类似这样的数组:

Array
(
    Array
    (
        [ID] => 1
        [parentcat_ID] => 0
    ),
    Array
    (
        [ID] => 2
        [parentcat_ID] => 0
    ),
    Array
    (
        [ID] => 6
        [parentcat_ID] => 1
    ),
    Array
    (
        [ID] => 7
        [parentcat_ID] => 1
    ),
    Array
    (
        [ID] => 8
        [parentcat_ID] => 6
    ),
    Array
    (
        [ID] => 9
        [parentcat_ID] => 1
    ),
    Array
    (
        [ID] => 13
        [parentcat_ID] => 7
    ),
    Array
    (
        [ID] => 14
        [parentcat_ID] => 8
    )

)

但我需要一个函数来递归地将每个项目放入相关父数组内的“子”数组中。所以它看起来更像这样:

Array
(
    Array
    (
        [ID] => 1
        [parentcat_ID] => 0
        [children] => Array (
            Array
            (
                [ID] => 6
                [parentcat_ID] => 1
                [childen] => Array (
                    Array
                    (
                        [ID] => 8
                        [parentcat_ID] => 6
                        [children] => Array (
                             Array
                             (
                                 [ID] => 14
                                 [parentcat_ID] => 8
                             )
                        )
                    )
                )
            ),
            Array
            (
                [ID] => 7
                [parentcat_ID] => 1
                [children] => Array(
                     Array
                     (
                         [ID] => 13
                         [parentcat_ID] => 7
                     )
                ) 
            ),
            Array
            (
                [ID] => 9
                [parentcat_ID] => 1
            )

        )
    )
    Array
    (
        [ID] => 2
        [parentcat_ID] => 0

    )

)

我希望这是有道理的!

【问题讨论】:

    标签: php arrays recursion tree tree-traversal


    【解决方案1】:

    试一试(在 php 5.2 下测试):

    $inArray = 数组( 数组('ID' => '1', 'parentcat_ID' => '0'), 数组('ID' => '2', 'parentcat_ID' => '0'), 数组('ID' => '6', 'parentcat_ID' => '1'), 数组('ID' => '7', 'parentcat_ID' => '1'), 数组('ID' => '8', 'parentcat_ID' => '6'), 数组('ID' => '9', 'parentcat_ID' => '1'), 数组('ID' => '13', 'parentcat_ID' => '7'), 数组('ID' => '14','parentcat_ID' => '8'), ); 函数 makeParentChildRelations(&$inArray, &$outArray, $currentParentId = 0) { if(!is_array($inArray)) { 返回; } if(!is_array($outArray)) { 返回; } foreach($inArray as $key => $tuple) { if($tuple['parentcat_ID'] == $currentParentId) { $tuple['children'] = array(); makeParentChildRelations($inArray, $tuple['children'], $tuple['ID']); $outArray[] = $元组; } } } $outArray = 数组(); makeParentChildRelations($inArray, $outArray); print_r($outArray);

    【讨论】:

    • 虽然你的解决方案可以完成这项工作,但它的缺点是它使用递归,这本身并不是必需的。
    • @fireeyedboy:迭代是人为的,递归是神的。 ;P 开个玩笑。当然还有其他方法。
    • 这是递归非常有用的典型案例。并不是说有必要。
    【解决方案2】:

    我最近回答了一个类似的问题。 Here 是。希望它适合您的需求。如果没有,请告诉我,我会根据您的规格进行调整。

    编辑
    好的,这是调整后的版本,应该可以满足您的需求。

    function generateMultiArray( array $flatArray )
    {
    
        // initiate result array
        $multiArray = array();
    
        // iterate $flatArray
        foreach( $flatArray as $item )
        {
            // for convenience, initiate these vars
            $id = $item[ 'ID' ];
            $parentId = $item[ 'parentcat_ID' ];
    
            // initiate this item's children array;
            $item[ 'children' ] = array();
    
            // if parent doesn't exist yet, initiate it along with an empty 'children' array
            if( !isset( $multiArray[ $parentId ] ) )
            {
                $multiArray[ $parentId ] = array(
                    'children' => array()
                );
            }
    
            // if this item is initiated already (as being a parent) merge it with the current item
            $multiArray[ $id ] = isset( $multiArray[ $id ] ) ? $multiArray[ $id ] + $item : $item;
    
            // add this item to the parents children collection by reference (for efficiency)
            $multiArray[ $parentId ][ 'children' ][ $id ] = &$multiArray[ $id ];
    
        }
    
        return $multiArray;
    }
    

    请注意,此函数还可以将所有项作为结果数组的根项进行访问,并以它们的 ID 作为索引。

    因此,要访问具有任意 id n 的项的子项,您可以:

    $multiArray = generateMultiArray( $yourFlatArray );
    $children = $multiArray[ n ][ 'children' ]; // replace n with the id
    

    编辑 2
    忘记为不是父项的项目启动子数组;现在添加。否则在尝试访问它时会导致通知:

    $multiArray = generateMultiArray( $yourFlatArray );
    $children = $multiArray[ $someIdWithoutChildren ][ 'children' ];
    

    【讨论】:

    • 我有点看到它的发展方向,但调整它会非常方便:)
    • 我知道它是如何工作的,但是它没有将数组“移动”到“子”数组中,而是复制它们(或不取消设置仍处于根级别的项目)
    • @Joel:实际上是在引用它们,而不是重复。我想你可能会喜欢让所有项目仍然可以在根级别访问的额外便利。我自己经常使用它,因为它也使循环更深嵌套项的子项变得容易。
    • 是的,没错,我一定会把它保存在我的 sn-p 存储库中 :) 谢谢。
    • 我知道这很旧,但这个答案对我帮助很大。谢谢。
    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    相关资源
    最近更新 更多