<?php
// https://axenov.dev/php-trees-without-recursion/
// функция построения дерева без рекурсии
function tree(
array $flat_list,
string $fk = 'hid',
string $pk = 'id',
): array {
$tree = [];
foreach ($flat_list as &$node) {
$references[$node[$pk]] = &$node;
if (empty($node[$fk])) {
$tree[$node[$pk]] = &$node;
} else {
$references[$node[$fk]]['children'][] = &$node;
}
}
return $tree;
}
//============================================
// Кейс 1. Допустим, массив неассоциирован
//============================================
// пример вспомогательной фукции для ассоциации массива
function key_by_field(array $flat_list, string $pk = 'id'): array
{
$result = [];
foreach ($flat_list as $element) {
$result[$element[$pk]] = $element;
}
return $result;
}
// исходные данные
$data = <<<JSON
[
{ "id": 1, "hid": null, "title": "Root" },
{ "id": 2, "hid": 1, "title": "Branch 1" },
{ "id": 3, "hid": 2, "title": "Leaf 1.1" },
{ "id": 5, "hid": 1, "title": "Branch 2" },
{ "id": 6, "hid": 5, "title": "Leaf 2.1" },
{ "id": 4, "hid": 2, "title": "Leaf 1.2" },
{ "id": 7, "hid": 5, "title": "Leaf 2.2" }
]
JSON;
$json = json_decode($data, JSON_OBJECT_AS_ARRAY | JSON_THROW_ON_ERROR);
$json = key_by_field($json);
// формирование нового списка элементов
print_r(tree($json));
//============================================
// Кейс 2. Допустим, массив ассоциирован
//============================================
$data2 = <<<JSON
{
"1": { "id": 1, "hid": null, "title": "Root" },
"3": { "id": 2, "hid": 2, "title": "Leaf 1.1" },
"2": { "id": 3, "hid": 1, "title": "Branch 1" },
"5": { "id": 5, "hid": 1, "title": "Branch 2" },
"6": { "id": 6, "hid": 5, "title": "Leaf 2.1" },
"4": { "id": 4, "hid": 2, "title": "Leaf 1.2" },
"7": { "id": 7, "hid": 5, "title": "Leaf 2.2" }
}
JSON;
$json2 = json_decode($data2, JSON_OBJECT_AS_ARRAY | JSON_THROW_ON_ERROR);
// формирование нового списка элементов
print_r(tree($json2));
- Output for 8.0.1 - 8.0.30, 8.1.0 - 8.1.30, 8.2.0 - 8.2.25, 8.3.0 - 8.3.14
- Array
(
[1] => Array
(
[id] => 1
[hid] =>
[title] => Root
[children] => Array
(
[0] => Array
(
[id] => 2
[hid] => 1
[title] => Branch 1
[children] => Array
(
[0] => Array
(
[id] => 3
[hid] => 2
[title] => Leaf 1.1
)
[1] => Array
(
[id] => 4
[hid] => 2
[title] => Leaf 1.2
)
)
)
[1] => Array
(
[id] => 5
[hid] => 1
[title] => Branch 2
[children] => Array
(
[0] => Array
(
[id] => 6
[hid] => 5
[title] => Leaf 2.1
)
[1] => Array
(
[id] => 7
[hid] => 5
[title] => Leaf 2.2
)
)
)
)
)
)
Array
(
[1] => Array
(
[id] => 1
[hid] =>
[title] => Root
[children] => Array
(
[0] => Array
(
[id] => 3
[hid] => 1
[title] => Branch 1
)
[1] => Array
(
[id] => 5
[hid] => 1
[title] => Branch 2
[children] => Array
(
[0] => Array
(
[id] => 6
[hid] => 5
[title] => Leaf 2.1
)
[1] => Array
(
[id] => 7
[hid] => 5
[title] => Leaf 2.2
)
)
)
)
)
)
preferences:
43.94 ms | 418 KiB | 5 Q