Как правильно создать дерево категорий?

Рейтинг: 0Ответов: 1Опубликовано: 13.07.2023

Есть массив с данными, в котором могут быть элементы с parentId == 0, и элементы со значениями в parentId для которых нет элемента c соответствующим 'id' (item_6, item_7) , такие элементы должны быть на 1 уровне вложенности $result, с каждым уровнем вложенности к title элемента добавляется префикс в виде табуляции, количество уровней вложенности не ограничивается

$data = [
    [
        'id' => 50,
        'title' => 'item_1',
        'parentId' => 0,
    ],
    [
        'id' => 55,
        'title' => 'item_2',
        'parentId' => 0,
    ], 
    [
        'id' => 90,
        'title' => 'item_3',
        'parentId' => 80,
    ], 
    [
        'id' => 70,
        'title' => 'item_4',
        'parentId' => 80,
    ], 
    [
        'id' => 85,
        'title' => 'item_5',
        'parentId' => 80,
    ], 
    [
        'id' => 80,
        'title' => 'item_6',
        'parentId' => 800,
    ], 
    [
        'id' => 82,
        'title' => 'item_7',
        'parentId' => 500,
    ], 
];


function createTree(array $items, int $sub = 0, string $tab = '')
{
    $result = [];

    if ($sub > 0) $tab .= '    ';
    
    foreach ($items as $item) {
        
        if ($sub == $item['parentId'] ) {
            $result[$item['id']] = $tab . $item['title'];
            $result += createTree($items, $item['id'], $tab);
        }
    }

    return $result;
}

Можно ли средствами php модифицировать функцию createTree таким образом, чтобы c текущими данными она возвращала массив вида

Array
(
    [50] => item_1,
    [55] => item_2,
    [80] => item_6,
    [90] =>    item_3,
    [70] =>    item_4,
    [85] =>    item_5,
    [82] => item_7
)

?

в текущем варианте возвращает

Array
(
    [50] => item_1
    [55] => item_2
)

Ответы

▲ 0Принят

У Вас в примере все работает, но только для корневых элементов с parentId='0', чтобы работало в вашем случае, надо составить список всех корневых элементов и для каждого вызвать функцию построения дерева

$data = [
    [
        'id' => 50,
        'title' => 'item_1',
        'parentId' => 0,
    ],
    [
        'id' => 55,
        'title' => 'item_2',
        'parentId' => 0,
    ], 
    [
        'id' => 90,
        'title' => 'item_3',
        'parentId' => 80,
    ], 
    [
        'id' => 70,
        'title' => 'item_4',
        'parentId' => 80,
    ], 
    [
        'id' => 85,
        'title' => 'item_5',
        'parentId' => 80,
    ], 
    [
        'id' => 80,
        'title' => 'item_6',
        'parentId' => 800,
    ], 
    [
        'id' => 82,
        'title' => 'item_7',
        'parentId' => 500,
    ], 
];

function GenerateRootArray($items)
{
    $arrid=[];
    $arrroot=[];
    $result=[];
    // Создаем список всех id
    foreach ($items as $item) {
        if (!(in_array($item['id'],$arrid))) {
            array_push($arrid,$item['id']);
        }
    }
    // если parentId не ссылается на какой-либо существующий id, считаем его корневым и вызываем построение дерева для него
    foreach ($items as $item) {
        if (!(in_array($item['parentId'],$arrid)) &&  !(in_array($item['parentId'],$arrroot))) {
            array_push($arrroot,$item['parentId']);
            $result +=createTree($items, $item['parentId'], 1); 
        }
    }
return $result; 
}

function createTree(array $items, int $sub = 0,int $asroot = 0, string $tab = '')
{
    $result = [];
    if ($asroot == 0) {$tab .= '    ';}
    foreach ($items as $item) {
        if ($sub == $item['parentId'] ) {
            $result[$item['id']] = $tab . $item['title'];
            $result += createTree($items, $item['id'], 0, $tab);
        }
    }
    return $result;
}

print_r(GenerateRootArray($data),false);

результат:

Array
(
    [50] => item_1
    [55] => item_2
    [80] => item_6
    [90] =>     item_3
    [70] =>     item_4
    [85] =>     item_5
    [82] => item_7
)