0

How can I convert a tree like array to two dimensional linear array? Still now I am stuck into this question. May be somebody ask this question but yet now I didn't get a proper way.

$str='[{"id":1},{"id":2,"children":[{"id":3,"children":[{"id":4}]},{"id":5,"children":[{"id":6},{"id":7,"children":[{"id":8}]}]},{"id":9},{"id":10}]},{"id":11,"children":[{"id":12}]}]'

This is my json string when I convert it to array using json_decode() function. I got the following result

    Array
    (
        [0] => stdClass Object
            (
                [id] => 1
            )
        [1] => stdClass Object
            (
                [id] => 2
                [children] => Array
                    (
                        [0] => stdClass Object
                            (
                                [id] => 3
                                [children] => Array
                                    (
                                        [0] => stdClass Object
                                            (
                                                [id] => 4
                                            )
                                    )
                            )
                        [1] => stdClass Object
                            (
                                [id] => 5
                                [children] => Array
                                    (
                                        [0] => stdClass Object
                                            (
                                                [id] => 6
                                            )
                                    )
                            )
                        [2] => stdClass Object
                            (
                                [id] => 7
                            )
                        [3] => stdClass Object
                            (
                                [id] => 8
                            )
                    )
            )
        [2] => stdClass Object
            (
                [id] => 9
                [children] => Array
                    (
                        [0] => stdClass Object
                            (
                                [id] => 10
                            )
                    )
            )
    )

This is like a tree structure but I need to convert it into a two dimensional array like

 Array
    (
        [0] => Array
            (
                [parent] => 0
                [id] => 1
            )

        [1] => Array
            (
                [parent] => 0
                [id] => 2
            )

        [2] => Array
            (
                [parent] => 2
                [id] => 3
            )

        [3] => Array
            (
                [parent] => 3
                [id] => 4
            )

        [4] => Array
            (
                [parent] => 2
                [id] => 5
            )

        [5] => Array
            (
                [parent] => 5
                [id] => 6
            )

        [6] => Array
            (
                [parent] => 2
                [id] => 7
            )

        [7] => Array
            (
                [parent] => 2
                [id] => 8
            )

        [8] => Array
            (
                [parent] => 0
                [id] => 9
            )

        [9] => Array
            (
                [parent] => 0
                [id] => 10
            )

    )
Lal krishnan S L
  • 1,684
  • 1
  • 16
  • 32
  • What have you tried? You're going to either need a recursive function or a loop, or a combination of both. This isn't really a difficult task, but I suggest you have a look through similar questions here about this because I know this situation has many questions and answers already – scrowler Jul 21 '14 at 04:34
  • @scrowler Actually I am really stuck with problem. still now I didn't get any idea... – Lal krishnan S L Jul 21 '14 at 05:10

1 Answers1

1

You'll need to write a recursive function and/or a loop to sort your object into an array like the one you specified.

I'll start by saying that in future if you could post sample data and expected output that actually matches what you want and expect that would be great - because I just spent ten minutes working out why my function is telling me that the parent of id 7 is id 5 when your example says it should be 2, when your JSON and your example array are actually different - annoying.

Anyway, here's the idea:

  • Recursive function to check for children in the passed array. If they exist, call the function again on its children. Add the current to the output array regardless of whether there are children or not.
  • &$output = output variable passed by reference, so you don't need to return anything and can access the output variable without a global call.
  • $parent_id represents the parent id each time you're iterating over children. In the first cases where the node doesn't have a parent, the declaration $parent_id = 0 will define your "default" parent ID. Otherwise, the parent ID is passed each time you go deeper.
function checkForChildrenOtherwiseAddToArray(&$output, $array, $parent_id = 0) {
    // loop through all sub-arrays inside this instance (if any)
    foreach($array as $each) {
        // check for children
        if(isset($each->children)) {
            // go deeper, passing in children and parent ID
            checkForChildrenOtherwiseAddToArray($output, $each->children, $each->id);
        }
        // add current iteration to array as well
        $output[] = array(
            'parent' => $parent_id,
            'id' => $each->id
        );
    }
}

Example use:

$your_array = json_decode($str);
$output = array();
checkForChildrenOtherwiseAddToArray($output, $your_array);

This will give you results that are seemingly un-ordered because of the recursive nature of this function. To sort by id for example you could use usort():

usort($output, function($a, $b) {
    return $a['id'] - $b['id'];
});

... and your example output would be:

Array
(
    [0] => Array
        (
            [parent] => 0
            [id] => 1
        )

    [1] => Array
        (
            [parent] => 0
            [id] => 2
        )

    [2] => Array
        (
            [parent] => 2
            [id] => 3
        )

    [3] => Array
        (
            [parent] => 3
            [id] => 4
        )

    [4] => Array
        (
            [parent] => 2
            [id] => 5
        )

    [5] => Array
        (
            [parent] => 5
            [id] => 6
        )

    [6] => Array
        (
            [parent] => 5
            [id] => 7
        )

    [7] => Array
        (
            [parent] => 7
            [id] => 8
        )

    [8] => Array
        (
            [parent] => 2
            [id] => 9
        )

    [9] => Array
        (
            [parent] => 2
            [id] => 10
        )

    [10] => Array
        (
            [parent] => 0
            [id] => 11
        )

    [11] => Array
        (
            [parent] => 11
            [id] => 12
        )

)
Community
  • 1
  • 1
scrowler
  • 24,273
  • 9
  • 60
  • 92