Reputation: 3493
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:
Upvotes: 0
Views: 1300
Reputation: 350272
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']; });
Upvotes: 3