1

I am trying to construct a hierarchy of comments so some have to be nested under each other.

The initial array is something like this:

$comments = [
    [   
        'id'=> 1, 
        'parent_id'=> null,
        'children'=> [],
    ],
    [   
        'id'=> 2, 
        'parent_id'=> null,
        'children'=> [],
    ],
    [   
        'id'=> 3, 
        'parent_id'=> null,
        'children'=> [],
    ],
    [   
        'id'=> 4, 
        'parent_id'=> 2,
        'children'=> [],
    ],
    [   
        'id'=> 5, 
        'parent_id'=> 3,
        'children'=> [],
    ],
    [   
        'id'=> 6, 
        'parent_id'=> 4,
        'children'=> [],
    ],
    [   
        'id'=> 7, 
        'parent_id'=> 4,
        'children'=> [],
    ],
];

The output for the above array should be something like this:

$comments = [
    [   
        'id'=> 1, 
        'parent_id'=> null,
        'children'=> [],
    ],
    [   
        'id'=> 2, 
        'parent_id'=> null,
        'children'=> [
            [   
                'id'=> 4, 
                'parent_id'=> 2,
                'children'=> [
                    [   
                        'id'=> 6, 
                        'parent_id'=> 4,
                        'children'=> [],
                    ],
                    [   
                        'id'=> 7, 
                        'parent_id'=> 4,
                        'children'=> [],
                    ],
                ],
            ],
        ],
    ],
    [   
        'id'=> 3, 
        'parent_id'=> null,
        'children'=> [
            [   
                'id'=> 5, 
                'parent_id'=> 3,
                'children'=> [],
            ],
        ],
    ],
];

My code below gets the top part right but misses the second level children:

// organize comments into a hierarchy
$tree = array_map(function($comment) use ($comments) {
    $children = [];
    $comments = array_map(function($child) use ($comment, &$children) {
        // return [$child['parent_id'], $comment['id']];
        if($child['parent_id'] == $comment['id']){
            $children[] = $child;
        }
        return $child;
    }, $comments);
    $comment['children'] = $children;
    return $comment;
}, $comments);

// remove children from the top
return $comments = array_filter($tree, function($child) {
    return !$child['parent_id'];
});
2
  • Possible duplicate of create array tree from array list Commented Jan 28, 2018 at 21:59
  • I tried that example and it didn't work for me. Kindly do a test with my data first. Commented Jan 28, 2018 at 22:01

1 Answer 1

1

You can use the code posted in this answer (so really this question is a duplicate), but obviously you have to take note of the differences:

  • Your input variable name is different
  • The parent property name is slightly different
  • The root nodes have value null as opposed to 0 in the referenced answer

Because of the last point you must pass $new[null] as second argument to createTree.

Here is the code adapted to your variable names and the above comment taken into account:

$new = array();
foreach ($comments as $a){
    $new[$a['parent_id']][] = $a;
}   
$tree = createTree($new, $new[null]);
print_r($tree);

function createTree(&$list, $parent){
    $tree = array();
    foreach ($parent as $k=>$l){
        if(isset($list[$l['id']])){
            $l['children'] = createTree($list, $list[$l['id']]);
        }
        $tree[] = $l;
    } 
    return $tree;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The null part must have been what I missed.

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.