Создание многоуровневого массива с помощью parentIds в PHP

Я пытаюсь установить список, который может иметь несколько уровней, с помощью parentId определить его родителя. Первый объект parentId является ПУСТЫМ. Пример некоторых записей:

id parentId name
1    NULL     item1
2    NULL     item2
3    1        item3
4    2        item4
5    3        item5
6    3        item6

Так, 1 и 2 основные объекты; 3 ребенок 1; 4 ребенок 2; 5 ребенок 3 (который является ребенком 1 самим); 6 также ребенок 3 (который является ребенком 1 самим); и т.д.

Я застреваю, создавая массив, который правильно добавляет эти объекты к правильным уровням. Это должно быть похожим на это:


Array
(
    [1] => Array
        (
            [name] => item1
            [parentId] => 
            [children] => Array
                (
                    [3] => Array
                        (
                            [name] => item3
                            [parentId] => 1
                            [children] => Array
                                (
                                    [5] => Array
                                        (
                                            [name] => item5
                                            [parentId] => 3
                                        )

                                    [6] => Array
                                        (
                                            [name] => item6
                                            [parentId] => 3
                                        )

                                )

                        )

                )

        )

    [2] => Array
        (
            [name] => item2
            [parentId] => 
            [children] => Array
                (
                    [4] => Array
                        (
                            [name] => item4
                            [parentId] => 2
                        )

                )

        )

)

Но скажите, что я прохожу все использование объектов foreach(), и я добираюсь до объекта 5. Его порожденный равняется 3, но в той точке, я понятия не имею, где эти родительские 3 расположены в массиве, и как добавить детей к тому родителю.

Существует ли прием, чтобы циклично выполниться через эти объекты и поместить их всех на месте правильный путь?

7
задан Alec 16 February 2010 в 14:12
поделиться

3 ответа

Вот

// your original data as an array
$data = array(
    array(
        'id' => 1,
        'parentId' => null,
        'name' => 'item1'
    ),
    array(
        'id' => 2,
        'parentId' => null,
        'name' => 'item2'
    ),
    array(
        'id' => 3,
        'parentId' => 1,
        'name' => 'item3'
    ),
    array(
        'id' => 4,
        'parentId' => 2,
        'name' => 'item4'
    ),
    array(
        'id' => 5,
        'parentId' => 3,
        'name' => 'item5'
    ),
    array(
        'id' => 6,
        'parentId' => 3,
        'name' => 'item6'
    ),
);

Рекурсивная функция

function buildTree( $ar, $pid = null ) {
    $op = array();
    foreach( $ar as $item ) {
        if( $item['parentId'] == $pid ) {
            $op[$item['id']] = array(
                'name' => $item['name'],
                'parentId' => $item['parentId']
            );
            // using recursion
            $children =  buildTree( $ar, $item['id'] );
            if( $children ) {
                $op[$item['id']]['children'] = $children;
            }
        }
    }
    return $op;
}

print_r( buildTree( $data ) );

/*
Array
(
    [1] => Array
        (
            [name] => item1
            [parentId] => 
            [children] => Array
                (
                    [3] => Array
                        (
                            [name] => item3
                            [parentId] => 1
                            [children] => Array
                                (
                                    [5] => Array
                                        (
                                            [name] => item5
                                            [parentId] => 3
                                        )

                                    [6] => Array
                                        (
                                            [name] => item6
                                            [parentId] => 3
                                        )

                                )

                        )

                )

        )

    [2] => Array
        (
            [name] => item2
            [parentId] => 
            [children] => Array
                (
                    [4] => Array
                        (
                            [name] => item4
                            [parentId] => 2
                        )

                )

        )

)
*/
11
ответ дан 6 December 2019 в 19:36
поделиться

Вы должны использовать идентификатор элемента в качестве значения ключа для массива, чтобы вы могли добавить элемент в его родительский элемент следующим образом:

$array[$parentID]['children'][$childID] = array();
1
ответ дан 6 December 2019 в 19:36
поделиться

Вместо записи нового System.Text.ASCIIEncoding () следует написать System.Text.Encoding.ASCII .

Также вместо этого я рекомендую использовать UTF8.

Кроме этого, ваш код выглядит довольно хорошо.

-121--3713214-

Подкаст SitePoint - это Патрик О'Киф (@ ifroggy), Стефан Сегрейвс (@ ssegraves), Штифтик Уильямс (@ Williamsba) и Кевин Янк (@ sentience). (@% имя пользователя твиттера%)

-121--1792425-

Первое, что приходит на ум, это просто плоская версия того, что у вас там есть:

array (
[0] => array(
    'name' => 'item1',
    'parent' => null
    ),
[1] => array(
    'name' => 'item2',
    'parent' => null
    ),
[3] => array(
    'name' => 'item3',
    'parent' => 0
    ),
[4] => array(
    'name' => 'item4',
    'parent' => 3
    ),
[5] => array(
    'name' => 'item5',
    'parent' => 1
    ),
[6] => array(
    'name' => 'item6',
    'parent' => 1
    ), );

В основном, вы только когда-либо ссылаетесь на родителя. Чтобы найти всех детей, нужно пройти через массив. Однако начальное время установки было бы довольно быстрым.

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

array (
[0] => array(
    'name' => 'item1',
    'parent' => null,
    'children' = array(3)
    ),
[1] => array(
    'name' => 'item2',
    'parent' => null
    'children' = array(5, 6)
    ),
[3] => array(
    'name' => 'item3',
    'parent' => 0
    'children' = array(4)
    ),
[4] => array(
    'name' => 'item4',
    'parent' => 3
    'children' = array()
    ),
[5] => array(
    'name' => 'item5',
    'parent' => 1
    'children' = array()
    ),
[6] => array(
    'name' => 'item6',
    'parent' => 1
    'children' = array()
    ), );

В этом, вы бы добавить все дочерние индексы к родителю. Это займет немного больше времени, но последующее время доступа будет быстрым. Когда вы выясняете родителей, вы просто добавляете к родительскому массиву детей.

Единственным реальным недостатком второго подхода является то, что если вы хотите добавить или удалить предмет, вы должны помнить, чтобы вернуться назад и обновить дочерний массив для родителя.

1
ответ дан 6 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: