开发者

Recreate array from flat (where child arrays store index of parent array) to multidimensional?

I am trying to take a flat array and recreate it so that it's multidimensional. I've been looking into array_combine and array_merge, but I'm not sure that either of those will give me what I'm hoping for...

The array, in it's current form (and this is just a simplified example):

Array
(
    [0] => stdClass Object
        (
            [tid] => 31
            [name] => Safeway
            [parents] => Array
                (
                    [0] => 0
                )

        )

    [1] => stdClass Object
        (
            [tid] => 32
            [name] => Dairy
            [parents] => Array
                (
                    [0] => 31
                )

        )

    [2] => stdClass Object
        (
            [tid] => 33
            [name] => Milk
            [parents] => Array
                (
                    [0] => 32
                )

        )
)

I'm trying to create a multidimensional array where each object is a subarray of it's parent. So, in the example above, I'm trying to output:

Array
(
    [0] => stdClass Object
        (
            [tid] => 31
            [name] => Safeway
            [children] => Array
                (
   开发者_运维百科                 [tid] => 32
                    [name] => Dairy
                    [children] => Array
                        (
                            [tid] => 33
                            [name] => Milk
                        )
                )

        )
)


First off, what you are showing is not an multidimensional array, but an array of StdClass objects.

If it's alright with you to make them truely arrays then this might do it:

// initiate result array
$multiArray = array();

// assume $items is your current array
foreach( $items as $item )
{
    // cast StdClass to array
    $objToArray = (array) $item;

    // if this item is initiated already merge it with the current item
    $multiArray[ $objToArray[ 'tid' ] ] = isset( $multiArray[ $objToArray[ 'tid' ] ] ) ? $multiArray[ $objToArray[ 'tid' ] ] + $objToArray : $objToArray;

    foreach( $objToArray[ 'parents' ] as $parentId )
    {
        // if parents don't exist yet, initiate them
        if( !isset( $multiArray[ $parentId ] ) )
        {
            $multiArray[ $parentId ] = array(
                'children' => array()
            );
        }

        // add this item to the parents children collection by reference (for efficiency)
        $multiArray[ $parentId ][ 'children' ][ $objToArray[ 'tid' ] ] = &$multiArray[ $objToArray[ 'tid' ] ];
    }
}

With this you can easily find items by id with:

$item = $multiArray[ $someId ];

And to get a child:

$child = $item[ 'children' ][ $someChildId ];

Or all children:

$children = $item[ 'children' ];

EDIT
Ok, I've tested it now, and it seems to work fine after adding some missing semicolons.


Ok, I'm making some assumptions here:

  • Each element has only 1 parent, so the parents array will have only 1 tid
  • The array is sorted such that children will appear only after their parents
  • Top-level elmenets will have parent = 0

Given that, try this code:

$original = array ( ... your original array ... );
$nested = array ();

$n = count($original);
for ($i = 0; $i < $n; ++$i)
{
    $nested[$original[$i]->tid] = $original[$i];
    $nested[$original[$i]->tid]->children = array ();
}

while ($n-- && $current = $original[$n])
    if ($current->parents[0] != 0 && $current->parents[0] != $current->tid)
    {
        $nested[$current->parents[0]]->children[] = $current;
        unset ($nested[$current->tid]);
    }
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜