Я пытаюсь получить многомерный массив, сравнивая значения [id] со значениями [parent_id] из массива следующим образом:

Array
(
    [0] => Array
        (
            [id] => 101
            [title] => parent_101
            [parent_id] => 0
            [level] => 1

        )

    [1] => Array
        (
            [id] => 118
            [title] => parent_118
            [parent_id] => 0
            [level] => 1

        )

    [2] => Array
        (
            [id] => 119
            [title] => child_119
            [parent_id] => 118
            [level] => 2
        )

    [4] => Array
        (
            [id] => 173
            [title] => subchild_173
            [parent_id] => 119
            [level] => 3

        )

    [5] => Array
        (
            [id] => 120
            [title] => child_120
            [parent_id] => 118
            [level] => 2
        )

    [6] => Array
        (
            [id] => 145
            [title] => deeperchild_145
            [parent_id] => 173
            [level] => 4
        )

)

Результатом должен быть новый массив, подобный этому:

Array
(
    [0] => Array
        (
            [title] => parent_101
            [id] => 101
            [parent_id] => 1
            [level] => 1
            [childrens] => Array
                (
                )

        )

    [1] => Array
        (
            [id] => 118
            [title] => parent_118
            [parent_id] => 1
            [level] => 1
            [childrens] => Array
                (
                    [0] => Array
                        (
                            [id] => 119
                            [title] => child_119
                            [parent_id] => 118
                            [level] => 2
                            [deeper] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 173
                                            [title] => subchild_173
                                            [parent_id] => 119
                                            [level] => 3
                                            [deeperchild] => Array
                                                (
                                                    [id] => 145
                                                    [title] => deeperchild_145
                                                    [parent_id] => 173
                                                    [level] => 4
                                                )
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [id] => 120
                            [title] => parent_120
                            [parent_id] => 118
                            [level] => 2
                            [deeper] => Array
                                 (
                                 )                      
                       )
                )
        )
)

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

> $parentsitms = array(); $deeperArr  = array(); $childsArr = array();
> $childparent = array(); $menu = array();
> 
> foreach ($list as $items) {
> 
>     if($items->level==='1'):
>         $idparent =  $items->id; 
>         $parents = $items->title; 
>         $parentsitms[] = ['id'=>$items->id,'title'=>$items->title,'parent_id'=>$items->parent_id,'level'=>$items->level];  
> 
>     endif;
> 
> }
>             foreach ($parentsitms as $menuitm) {
>                 $parents = $menuitm;
> 
>                 foreach($list as $chd){
>                     
>                         if($menuitm['id'] === $chd->parent_id):
>                             $childparent = $chd->id;
>                             $childsItms = ['id'=>$chd->id,'title'=>$chd->title,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
>                             $childsArr[] = [array_merge($childsItms,array('deeper'=>array()))];
>                         endif;
> 
>                         if($childparent === $chd->parent_id):
>                             $array =  ['title'=>$chd->title,'id'=>$chd->id,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
>                             $deeperArr[] = ['id'=>$chd->id,'title'=>$chd->title,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
>                             $childsArr  = [array_merge($childsItms,array('deeper'=>$deeperArr))];
>                         endif;
> 
>                         ######## can't get the 4th level deeper ######
> 
>                         
>                  }
> 
>                     $menu[] = array_merge($parents,array('childrens'=>$childsArr));
>             }
> 
>             echo '<pre>'; print_r($menu);

Любая помощь очень ценится.

1
Znort 18 Дек 2019 в 20:58

1 ответ

Этот код использует нерекурсивный метод, который является более распространенным методом решения этого типа проблемы. Я предпочитаю этот метод, так как он делает только один проход через данные и может быть легче следовать (ИМХО).

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

// Order array so that they are in order of level
usort($list, function ( $a, $b ) { return $a['level'] <=> $b['level']; });

// Create start point with all of the items indexed by their ID
$output = array_column($list, null, "id");

// Work in reverse order
foreach ( array_reverse(array_column($list, "id")) as $id ) {
    $parent = $output[$id]['parent_id'];
    // If there is a parent to work with 
    if ( $parent != 0 )   {
        // Ensure that the add point is there
        if ( !isset($output[$parent]['children']) )  {
            $output[$parent]['children'] = [];
        }
        // Prepend the new item to the list (do this as the items
        // are added in reverse oder)
        array_unshift($output[$parent]['children'], $output[$id]);
        // Remove the old node from the base list
        unset($output[$id]);
    }
}

$output = array_values($output);
print_r($output);

дает ...

Array
(
    [0] => Array
        (
            [id] => 101
            [title] => parent_101
            [parent_id] => 0
            [level] => 1
        )

    [1] => Array
        (
            [id] => 118
            [title] => parent_118
            [parent_id] => 0
            [level] => 1
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 119
                            [title] => child_119
                            [parent_id] => 118
                            [level] => 2
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 173
                                            [title] => subchild_173
                                            [parent_id] => 119
                                            [level] => 3
                                            [children] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [id] => 145
                                                            [title] => deeperchild_145
                                                            [parent_id] => 173
                                                            [level] => 4
                                                        )

                                                )

                                        )

                                )

                        )

                    [1] => Array
                        (
                            [id] => 120
                            [title] => child_120
                            [parent_id] => 118
                            [level] => 2
                        )

                )

        )

)
1
Nigel Ren 18 Дек 2019 в 18:26