Сортировать набор результатов MPTT в многомерный массив PHP

Я экспериментировал с Модифицированной моделью обхода дерева предварительных заказов, мой код тестового примера возвращает результаты, как и ожидалось, однако у меня возникают проблемы с преобразованием 2D-массива в многомерный массив для его представления.

Вот пример результата трехуровневого меню, мне нужно преобразовать его в многомерный массив, чтобы я мог повторить его в TAL:

Array
(
    [0] => Array
        (
            [CategoryID] => 1
            [ParentID] => 0
            [CategoryName] => Default Parent
            [lt] => 1
            [rt] => 14
            [tree_depth] => 1
        )

    [1] => Array
        (
            [CategoryID] => 8
            [ParentID] => 1
            [CategoryName] => SysAdmin
            [lt] => 2
            [rt] => 7
            [tree_depth] => 2
        )

    [2] => Array
        (
            [CategoryID] => 2
            [ParentID] => 8
            [CategoryName] => Linux
            [lt] => 3
            [rt] => 4
            [tree_depth] => 3
        )

    [3] => Array
        (
            [CategoryID] => 3
            [ParentID] => 8
            [CategoryName] => Windows
            [lt] => 5
            [rt] => 6
            [tree_depth] => 3
        )

    [4] => Array
        (
            [CategoryID] => 5
            [ParentID] => 1
            [CategoryName] => Code
            [lt] => 8
            [rt] => 13
            [tree_depth] => 2
        )

    [5] => Array
        (
            [CategoryID] => 6
            [ParentID] => 5
            [CategoryName] => PHP
            [lt] => 9
            [rt] => 10
            [tree_depth] => 3
        )

    [6] => Array
        (
            [CategoryID] => 7
            [ParentID] => 5
            [CategoryName] => Perl
            [lt] => 11
            [rt] => 12
            [tree_depth] => 3
        )

)

Мне нужно структурировать данные так, чтобы у каждого родителя был ключ 'Children', представляющий собой массив повторяемых массивов, без ограничения количества дочерних элементов, которые может иметь родитель / ребенок / внук, ключ tree_depth автоматически обрабатывается СУБД, поэтому мне просто нужно изменить структуру массива.

Любые указатели очень ценятся, я играл с usort() и array_walk_recursive безрезультатно.

заранее спасибо

1 ответ

Решение

Я думаю простой foreach можно сделать трюк здесь (с помощью ссылок):

Настроить $menu ассоциативный массив $cat_id => $element_details_anb_children:

$menu = array(); $ref = array();
foreach( $tree as $d ) {
    $d['children'] = array();
    if( isset( $ref[ $d['ParentID'] ] ) ) { // we have a reference on its parent
        $ref[ $d['ParentID'] ]['children'][ $d['CategoryID'] ] = $d;
        $ref[ $d['CategoryID'] ] =& $ref[ $d['ParentID'] ]['children'][ $d['CategoryID'] ];
    } else { // we don't have a reference on its parent => put it a root level
        $menu[ $d['CategoryID'] ] = $d;
        $ref[ $d['CategoryID'] ] =& $menu[ $d['CategoryID'] ];
    }
}

Это должно построить два массива: многомерный массив, который вы хотите ($menu) и плоский массив, который содержит только ссылки для каждой категории. На каждой итерации она вкладывает категорию в своего родителя, если она уже существует (именно поэтому я сохраняю справочную таблицу). Конечно, это работает, только если ваш начальный $tree Массив упорядочен (т.е. родительский элемент предшествует своим дочерним элементам).

Другие вопросы по тегам