2

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

        )
)
0

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.