1

I have data that looks like this:

1          Root Catalog 
1/2        Main Website
1/2/4      Cold Beverages
1/2/4/19   Pop - Canned
1/2/4/20   Pop - Natural Low Calorie
1/2/4/21   Pop - Bottled - Large Plastic
1/2/4/22   Pop - Bottled - Small Plastic

And need to turn it into an array that looks like:

array(
        1 => array(
            'name' => 'Root Catalog',
            2      => array(
                'name' => 'Main Website',
                4      => array(
                    'name' => 'Cold Beverages',
                    19     => array(
                       'name' => 'Pop - Canned'
                    )
                    /*more numbers here*/
                )
            )
        )
    )

I can't figure out how to assign the array to the parent array while maintaining data integrity. The issue I'm encountering is that I can have between 1-n levels nested. I've tried exploding the string and reconstructing it using recursion, but it never turns out right. Any idea's I could try?

edit: Best Attempt so far:

foreach ($categories as $category) {
        $paths = explode('/', $category->getPath());
        $paths = array_reverse($paths);

        $temp = array('name' => $category->getName());

        foreach ($paths as $key => $value) {
            $temp = array($value => $temp);
        }

        $data = array_merge($data, $temp);
    }
1
  • What if you show your best attempt and we give you some hints what's wrong with it? Commented Oct 31, 2014 at 22:20

1 Answer 1

3
$data = array(
 '1'         =>   'Root Catalog', 
 '1/2'       =>   'Main Website',
 '1/2/4'     =>   'Cold Beverages',
 '1/2/4/19'  =>   'Pop - Canned',
 '1/2/4/20'  =>   'Pop - Natural Low Calorie',
 '1/2/4/21'  =>   'Pop - Bottled - Large Plastic',
 '1/2/4/22'  =>   'Pop - Bottled - Small Plastic'
);

$out = array();

foreach($data as $route => $value) // take every element of $data
{
    $path = explode('/', $route);  // split the route into elements 
    $current = &$out;              // get pointer to the root of the output array
    foreach($path as $level)       // traverse through the path
    {
       if (!isset($current[$level]))  // if branch does not exist, create it
          $current[$level] = array();

       $current = &$current[$level];  // set current pointer to that branch
    }
    $current['name'] = $value; // set leaf at the end of the branch
} 

print_r($out);  // output result

Result:

Array
(
    [1] => Array
        (
            [name] => Root Catalog
            [2] => Array
                (
                    [name] => Main Website
                    [4] => Array
                        (
                            [name] => Cold Beverages
                            [19] => Array
                                (
                                    [name] => Pop - Canned
                                )

                            [20] => Array
                                (
                                    [name] => Pop - Natural Low Calorie
                                )

                            [21] => Array
                                (
                                    [name] => Pop - Bottled - Large Plastic
                                )

                            [22] => Array
                                (
                                    [name] => Pop - Bottled - Small Plastic
                                )

                        )

                )

        )

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

2 Comments

@SGrimminck the main thing here are &, they help to access and modify sub-arrays directly.
@SGrimminck And it also have one disadvantage - the previous branch should be created before something goes into it. Probably can modify this, but have to run right now. Actually, fixed it - look at the updated code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.