0

I have a tree-like array and I need to marge or convert it to a flat array but I cannot make it work.

I am trying with this code:

$fakepages = array();
    $fakepages[0] = array('id' => 1, 'parent_id' => 0, 'title' => 'Parent Page');
    $fakepages[1] = array('id' => 2, 'parent_id' => 1, 'title' => 'Sub Page');
    $fakepages[2] = array('id' => 3, 'parent_id' => 2, 'title' => 'Sub Sub Page');
    $fakepages[3] = array('id' => 4, 'parent_id' => 3, 'title' => 'Another Parent Page');
    $fakepages[4] = array('id' => 5, 'parent_id' => 0, 'title' => 'Another Parent Page 5');
    $fakepages[5] = array('id' => 6, 'parent_id' => 2, 'title' => 'Another Parent Page 5');

    $tree = $this->buildTree($fakepages);
    return $tree;

private function buildTree(array $elements, $parentId = 0) {
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = $this->buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }

    return $branch;
}

And this is my sort (or merge or ...?) code. What's is the problem with my code and how can I fix this and make it like in the left picture?

private function findchild($trees)
{
    $arr = array();

    foreach ($trees as $tree) {

        if (isset($tree['children'])) {
            $this->mes[] = ['id'=>$tree['id'],'parent_id'=>$tree['parent_id']];
            $arr[] = $this->findchild($tree['children']);
        }
        else{
            $this->mes[] = ['id'=>$tree['id'],'parent_id'=>$tree['parent_id']];
            $arr[] = $tree;
        }
        return $arr;
    }
}
private $mes = [];

I have what is in the right part, but need to convert it to what is in the left part:

enter image description here

8
  • @Dekel I need save they to database and show it to user . Commented Oct 30, 2016 at 14:02
  • 2
    It looks like a PHP code, but your tags are javascript/jquery. What language are you looking for? Commented Oct 30, 2016 at 14:03
  • Did you try to write some code yourself? Commented Oct 30, 2016 at 14:03
  • 4
    Please post code as formatted text not images of code. There is no way for anyone to copy that to help you. Also not clear where you are trying to convert this Commented Oct 30, 2016 at 14:03
  • @Dekel yep sorry and thank you .. Commented Oct 30, 2016 at 14:06

1 Answer 1

3

You could use this PHP function, which assumes your data is an array of standard class objects:

function flatten($arr) {
    $result = [];
    foreach($arr as $item) {
        if (isset($item->children))
            $result = array_merge($result, flatten($item->children));
        unset($item->children);
        $result[] = $item;  
    }
    return $result;
}

Of course, if your original value is JSON, you need to first decode it and only then pass it to this function, like this:

$arr = json_decode($json);
// Flatten it
$arr = flatten($arr);
// Optionally sort the result
usort($arr, function($a, $b) { return $a->id - $b->id; });

See it run on eval.in

If your data consists of associative arrays (not "objects"), then, the code needs to use bracket notation instead of ->:

function flatten($arr) {
    $result = [];
    foreach($arr as $item) {
        if (isset($item['children']))
            $result = array_merge($result, flatten($item['children']));
        unset($item['children']);
        $result[] = $item;
    }
    return $result;
}

and the sort:

usort($arr, function($a, $b) { return $a['id'] - $b['id']; });
Sign up to request clarification or add additional context in comments.

1 Comment

You still have a problem? Just integrate this code into your project.

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.