PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID

Posted

技术标签:

【中文标题】PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID【英文标题】:PHP Traversing Function to turn single array into nested array with children - based on parent 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

    )

)

我希望这是有道理的!

【问题讨论】:

【参考方案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 存储库中 :) 谢谢。 我知道这很旧,但这个答案对我帮助很大。谢谢。

以上是关于PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XSLT 将单个子 xml 元素转换为 Json 数组

将嵌套数组转换为嵌套 html 块的递归 php 函数

PHP从遍历嵌套树模型构建数组

如何使用 PHP 将日期数组转换为 3 级嵌套列表

将带有数组的 JavaScript 对象转换为 PHP 数组

PHP将带有一些(重复)元素的XML转换为Json到Json数组[重复]