Преобразование плоского массива в определенный формат массива

Товарищи программисты PHP, рассмотрим следующий результат БД:

+---------+-----------+---------------+--------+
| node_id | parent_id | path          | branch |
+---------+-----------+---------------+--------+
|       1 |         0 | /1/           |   NULL |
|       2 |         1 | /1/2/         |   NULL |
|       3 |         2 | /1/2/3/       |      1 |
|       4 |         3 | /1/2/3/4/     |      1 |
|       8 |         4 | /1/2/3/4/8/   |      1 |
|       9 |         8 | /1/2/3/4/8/9/ |      1 |
|       7 |         4 | /1/2/3/4/7/   |      0 |
|       5 |         2 | /1/2/5/       |      0 |
|       6 |         5 | /1/2/5/6/     |      0 |
+---------+-----------+---------------+--------+

Как получить следующий массив PHP:

[
[
'id' => 1,
'parentId' => 0,
],
[
'id' => 2,
'parentId' => 1,
'nodes' => [
[ // when branch == 0
[
'id' => 5,
'parentId' => 2
],
[
'id' => 6,
'parentId' => 5
],
],
[ // when branch == 1
[
'id' => 3,
'parentId' => 2
],
[
'id' => 4,
'parentId' => 3,
'nodes' => [
[ // when branch == 0
[
'id' => 7,
'parentId' => 4
],
],
[ // when branch == 1
[
'id' => 8,
'parentId' => 4
],
[
'id' => 9,
'parentId' => 8
],
]
]
],
]
]
]
]

Функция должна работать с неограниченной глубиной.

Любая помощь будет принята с благодарностью, поскольку я бью стену.

1

Решение

Что-то вроде этого:

function buildTree($arr, $parentID)
{
$children = [];
foreach ($arr as $item) {
if ($item['parent_id'] == $parentID) {
array_push($children, [
'id'       => $item['node_id'],
'parentId' => $item['parent_id'],
'nodes'    => buildTree($arr, $item['node_id'])
]);
}
}

return $children;
}

$tree = buildTree($flat, null);

UPD:

function getBranches($arr, $parentID)
{
$branches = array();

foreach ($arr as $item) {
if ($item['parent_id'] == $parentID) {

$bKey = $item['branch'];
$node = array(
'id'       => $item['node_id'],
'parentId' => $item['parent_id']
);

$firstNodeChild = false;
if ($nodeChildren = getBranches($arr, $item['node_id'])) {
$hasKey = array_key_exists($bKey, $nodeChildren);
if ($hasKey && $nodeChildren[$bKey]) {
if (sizeof($nodeChildren[$bKey]) == 1) {
$firstNodeChild = $nodeChildren[$bKey][0];
unset($nodeChildren[$bKey]);
}
}
if ($nodeChildren) {
$node['nodes'] = $nodeChildren;
}
}
if (!array_key_exists($bKey, $branches)) {
$branches[$bKey] = array();
}
$branches[$bKey][] = $node;
if (false !== $firstNodeChild) {
$branches[$bKey][] = $firstNodeChild;
}

}
}
ksort($branches);

return $branches;
}

$tree = getBranches($arr, 0);
0

Другие решения

Других решений пока нет …