<?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));
preferences:
46.44 ms | 405 KiB | 5 Q