开发者

PHP Traversing Function to turn single array into nested array with children - based on parent id

I have an array similar to this:

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
    )

)

But I need a function to recursively put each item into a 'children' array inside the relevant parent array. So it would look more like this:

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] 开发者_StackOverflow社区=> 1
            )

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

    )

)

I hope that makes sense!


Give this a go (tested under php 5.2):

$inArray = 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'),     
);

function makeParentChildRelations(&$inArray, &$outArray, $currentParentId = 0) {
    if(!is_array($inArray)) {
        return;
    }

    if(!is_array($outArray)) {
        return;
    }

    foreach($inArray as $key => $tuple) {
        if($tuple['parentcat_ID'] == $currentParentId) {
            $tuple['children'] = array();
            makeParentChildRelations($inArray, $tuple['children'], $tuple['ID']);
            $outArray[] = $tuple;   
        }
    }
}

$outArray = array();
makeParentChildRelations($inArray, $outArray);

print_r($outArray);


I recently answered a similar question. Here it is. Hope it suits your needs. If not, let me know, and I'll adjust it to your specs.

EDIT
Alright, here is the adjusted version that should suit your needs.

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;
}

Mind you that this function also makes all items accessible as a root item of the result array with their ID as the index.

So, to access children of an item with arbitrary id n, you would do:

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

EDIT 2
Forgot to intitiate children array for items that aren't a parent; added now. Otherwise it would result in a notice when trying to access it with:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜