0

I have tree of objects:

array(4) (
    0 => object stdClass(14) {
        public id => string(1) "1"
        public parent_id => string(1) "0"
        public name => string(18) "Stationary engines"
        public uri => string(18) "stationary-engines"
        public created => string(19) "2012-11-19 15:15:34"
        public updated => NULL
        public subcategories => array(4) (
            0 => object stdClass(14) {
                public id => string(1) "5"
                public parent_id => string(1) "1"
                public name => string(6) "Yanmar"
                public uri => string(6) "yanmar"
                public created => string(19) "2012-11-19 15:23:36"
                public updated => NULL
                public subcategories => array(1) (
                    0 => object stdClass(14) {
                        public id => string(2) "15"
                        public parent_id => string(1) "5"
                        public name => string(18) "Yanmar subcategory"
                        public uri => string(18) "yanmar-subcategory"

                        public created => string(19) "2012-11-21 16:38:06"
                        public updated => NULL
                        public subcategories => array(1) (
                            0 => object stdClass(13) {
                                public id => string(2) "16"
                                public parent_id => string(2) "15"
                                public name => string(30) "Yanmar subcategory subcategory"
                                public uri => string(30) "yanmar-subcategory-subcategory"
                                public created => string(19) "2012-11-21 17:37:00"
                                public updated => NULL
                            }
                        )
                    }
                )
            }
            1 => object stdClass(13) {
                public id => string(1) "6"
                public parent_id => string(1) "1"
                public name => string(11) "Мercruiser"
                public uri => string(10) "mercruiser"
                public created => string(19) "2012-11-19 15:23:36"
                public updated => NULL
            }
            2 => object stdClass(13) {
                public id => string(1) "7"
                public parent_id => string(1) "1"
                public name => string(11) "Volvo-Penta"
                public uri => string(11) "volvo-penta"
                public created => string(19) "2012-11-19 15:24:49"
                public updated => NULL
            }
            3 => object stdClass(13) {
                public id => string(1) "8"
                public parent_id => string(1) "1"
                public name => string(27) "Basic configuration engines"
                public uri => string(27) "basic-configuration-engines"
                public created => string(19) "2012-11-19 15:24:49"
                public updated => NULL
            }
        )
    }
    1 => object stdClass(14) {
        public id => string(1) "2"
        public parent_id => string(1) "0"
        public name => string(10) "Generators"
        public uri => string(10) "generators"
        public created => string(19) "2012-11-19 15:15:58"
        public updated => NULL
        public subcategories => array(4) (
            0 => object stdClass(13) {
                public id => string(1) "9"
                public parent_id => string(1) "2"
                public name => string(6) "Diesel"
                public uri => string(6) "diesel"
                public created => string(19) "2012-11-19 15:34:38"
                public updated => NULL
            }
            1 => object stdClass(13) {
                public id => string(2) "10"
                public parent_id => string(1) "2"
                public name => string(8) "Gasoline"
                public uri => string(8) "gasoline"
                public created => string(19) "2012-11-19 15:34:38"
                public updated => NULL
            }
            2 => object stdClass(13) {
                public id => string(2) "11"
                public parent_id => string(1) "2"
                public name => string(6) "Kohler"
                public uri => string(6) "kohler"
                public created => string(19) "2012-11-19 15:35:35"
                public updated => NULL
            }
            3 => object stdClass(13) {
                public id => string(2) "12"
                public parent_id => string(1) "2"
                public name => string(13) "Fischer Panda"
                public uri => string(13) "fischer-panda"
                public created => string(19) "2012-11-19 15:36:14"
                public updated => NULL
            }
        )
    }
    2 => object stdClass(14) {
        public id => string(1) "3"
        public parent_id => string(1) "0"
        public name => string(14) "Boat equipment"
        public uri => string(14) "boat-equipment"
        public created => string(19) "2012-11-19 15:16:59"
        public updated => NULL
        public subcategories => array(1) (
            0 => object stdClass(13) {
                public id => string(2) "13"
                public parent_id => string(1) "3"
                public name => string(11) "Subcategory"
                public uri => string(11) "subcategory"
                public created => string(19) "2012-11-19 15:37:12"
                public updated => NULL
            }
        )
    }
    3 => object stdClass(14) {
        public id => string(1) "4"
        public parent_id => string(1) "0"
        public name => string(11) "Spare parts"
        public uri => string(11) "spare-parts"
        public created => string(19) "2012-11-19 15:16:59"
        public updated => NULL
        public subcategories => array(1) (
            0 => object stdClass(13) {
                public id => string(2) "14"
                public parent_id => string(1) "4"
                public name => string(11) "Consumables"
                public uri => string(11) "consumables"
                public created => string(19) "2012-11-19 15:37:39"
                public updated => NULL
            }
        )
    }
)

And I need to convert it to associative array like this:

array(
    '1' => 'category name',
    '3' => '   subcategory name',
    '4' => '      subcategory name',
    '2' => 'category2 name',
    '5' => '   subcategory2 name',
);

Each subcategory should be indented by spaces. But I'm not really familiar with recursion and need some help, I would really appreciate if you could help me. Thanks in advance.

UPDATE: I've ended up with following:

$options = array();
$this->to_array($tree, $options, '   ', 0);

function to_array($tree, & $target, $indention = '', $lvl = 0)
{
    foreach($tree as $leaf)
    {
        $target[$leaf->id] = str_repeat($indention, $lvl).$leaf->name;

        if (isset($leaf->subcategories))
        {
            $this->to_array($leaf->subcategories, $target, $indention, $lvl + 1);
        }
    }
}

any suggestions on improvement?

5
  • How would you fetch the nth id from the final array if all it's keys are id? Commented Nov 26, 2012 at 11:30
  • why you want like that an all the array's are same structure so use for each loop to loop through the data. Commented Nov 26, 2012 at 11:32
  • I don't think you can get it done like this. Each id key will overwrite the previous id key. Commented Nov 26, 2012 at 11:33
  • All your keys are belong to id Commented Nov 26, 2012 at 11:33
  • final array is for example only, instead of 'id' there would be id of the category, I've edited the question Commented Nov 26, 2012 at 11:38

1 Answer 1

1

I would go for something along the lines of:

function printArray($arr, &$target, $header = '') {
  foreach($arr as $category) {
    $target[$category->id] = $header . $category->name;
    printArray($category->subcategories, $target, $header . ' ');
  }
}

// And then, from your source
$targetArray = array();
printArray($source, $targetArray);

That doesn't deal with possible collisions, but if your data is coming from a single table, then collisions should not happen.

To customize even more, you pass the header modification as a parameter to the recursive function like:

function printArray($arr, &$target, $header = '', $headerIncrement = ' ') {
  foreach($arr as $category) {
    $target[$category->id] = $header . $category->name;
    printArray($category->subcategories, $target, $header . $headerIncrement, $headerIncrement);
  }
}

That would allow you to call it with

printArray($source, $target, '', '   ');
//or even
printArray($source, $target, '', '<span class="spacer">&nbsp;</span>');

And add styling in your css to change the spacing how you want.

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

3 Comments

Thank you, you've shown me the light! I've updated question, maybe you could make some improvements to this code?
I just update my code, i forgot to update the $header in the recursive call. Now $header will grow with each level. This would add &nbsp to each level. You can change the behavior by changing the recursive call (from $header . '&nbsp' to $header . '&nbsp;&nbsp;').
@UAMoto by using the header and increment, you are saving a for loop (in the str_repeat) for each call and that loop is not required since you are already in a loop doing the same count.

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.