不能理解多次嵌套数组的逻辑

时间:2018-12-12 09:07:43

标签: php codeigniter

我的函数逻辑有问题,我试图将数组嵌套X次,以使其看起来像是带有孩子的树。我将其与第一个孩子嵌套,但是当我深入时,我找不到解决方案可以将它们从Main数组中删除并添加到深处。“ parent”键是需要有子级的父元素的ID。任何帮助,请感谢。

function array_search_multidim($array, $column, $key){
    return (array_search($key, array_column($array, $column)));
}

public function get_all() {
    $full_menu = $this->Site_model->get_all_menu();
    usort($full_menu, function($a, $b){
        return strcmp($a->menu_order, $b->menu_order);
    });

    foreach($full_menu as $fm) {
        $mega_menu[] = array(
        'id'        => $fm->id,
        'text'      => $fm->title,
        'href'      => $fm->link,
        'icon'      => $fm->icon,
        'target'    => $fm->target,
        'title'     => $fm->name,
        'order'     => $fm->menu_order,
        'parent'    => $fm->parent
        );

        if($fm->parent != 0) {
            $child_menu[] = array(
            'id'        => $fm->id,
            'text'      => $fm->title,
            'href'      => $fm->link,
            'icon'      => $fm->icon,
            'target'    => $fm->target,
            'title'     => $fm->name,
            'order'     => $fm->menu_order,
            'parent'    => $fm->parent
            );
        }
    }

    foreach($child_menu as $cm) {
        $mega_menu[$this->array_search_multidim($mega_menu,'id',$cm['parent'])]['children'][] = array(
        'id'        => $cm['id'],
        'text'      => $cm['text'],
        'href'      => $cm['href'],
        'icon'      => $cm['icon'],
        'target'    => $cm['target'],
        'title'     => $cm['title'],
        'order'     => $cm['order'],
        'parent'    => $cm['parent']
        );
    }

    echo '<pre>';
        print_r($mega_menu);
        echo '</pre>';
    }

现在我能收到这样的数组

Array
(
    [0] => Array
        (
            [id] => 1
            [text] => Начало
            [href] => http://localhost/roni/#top
            [icon] => fas fa-home
            [target] => _self
            [title] => Начало
            [order] => 1
            [parent] => 0
        )

    [1] => Array
        (
            [id] => 4
            [text] => Споделен хостинг
            [href] => http://localhost/roni/#shared
            [icon] => fas fa-home
            [target] => _blank
            [title] => shared
            [order] => 1
            [parent] => 3
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 5
                            [text] => Софтуер
                            [href] => http://localhost/roni/#software
                            [icon] => fas fa-code
                            [target] => _self
                            [title] => software
                            [order] => 2
                            [parent] => 4
                        )

                )

        )

    [2] => Array
        (
            [id] => 2
            [text] => Интернет
            [href] => http://localhost/roni/#internet2
            [icon] => fas fa-wifi
            [target] => _top
            [title] => Интернет
            [order] => 2
            [parent] => 0
        )

    [3] => Array
        (
            [id] => 5
            [text] => Софтуер
            [href] => http://localhost/roni/#software
            [icon] => fas fa-code
            [target] => _self
            [title] => software
            [order] => 2
            [parent] => 4
        )

    [4] => Array
        (
            [id] => 3
            [text] => Хостинг
            [href] => http://localhost/roni/#hosting
            [icon] => fas fa-home
            [target] => _self
            [title] => hosting
            [order] => 3
            [parent] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 4
                            [text] => Споделен хостинг
                            [href] => http://localhost/roni/#shared
                            [icon] => fas fa-home
                            [target] => _blank
                            [title] => shared
                            [order] => 1
                            [parent] => 3
                        )

                )

        )

    [5] => Array
        (
            [id] => 6
            [text] => Сервиз
            [href] => http://localhost/roni/#service
            [icon] => fas fa-wrench
            [target] => _self
            [title] => service
            [order] => 5
            [parent] => 0
        )

    [6] => Array
        (
            [id] => 7
            [text] => Контакти
            [href] => http://localhost/#contacts
            [icon] => fas fa-address-book
            [target] => _self
            [title] => contacts
            [order] => 6
            [parent] => 0
        )

)

3 个答案:

答案 0 :(得分:1)

在get_all函数的第一个foreach中,每次将$ full_menu arrach元素添加到$ mega_menu中,如果$ fm-> parent!= 0(这意味着每个子元素都保存到数组的第一级)中,则会发生此事件。接下来,您要处理孩子。您只能(在数组的第一个维度上)保存$ fm-> parent == 0的那些元素。可以通过更改get_all中的条件来实现。

function array_search_multidim($array, $column, $key){
    return (array_search($key, array_column($array, $column)));
}

public function get_all() {
    $full_menu = $this->Site_model->get_all_menu();
    usort($full_menu, function($a, $b){
        return strcmp($a->menu_order, $b->menu_order);
    });

    foreach($full_menu as $fm) {
        if($fm->parent == 0) {
            $mega_menu[] = array(
                'id' => $fm->id,
                'text' => $fm->title,
                'href' => $fm->link,
                'icon' => $fm->icon,
                'target' => $fm->target,
                'title' => $fm->name,
                'order' => $fm->menu_order,
                'parent' => $fm->parent
            );
        } else {
            $child_menu[] = array(
                'id'        => $fm->id,
                'text'      => $fm->title,
                'href'      => $fm->link,
                'icon'      => $fm->icon,
                'target'    => $fm->target,
                'title'     => $fm->name,
                'order'     => $fm->menu_order,
                'parent'    => $fm->parent
            );
        }
    }

    foreach($child_menu as $cm) {
        $mega_menu[$this->array_search_multidim($mega_menu,'id',$cm['parent'])]['children'][] = array(
            'id'        => $cm['id'],
            'text'      => $cm['text'],
            'href'      => $cm['href'],
            'icon'      => $cm['icon'],
            'target'    => $cm['target'],
            'title'     => $cm['title'],
            'order'     => $cm['order'],
            'parent'    => $cm['parent']
        );
    }

    echo '<pre>';
    print_r($mega_menu);
    echo '</pre>';
}

答案 1 :(得分:1)

我将初始数据保留为对象,因为我想使用array_walk_recursive()查找要添加节点的点。但是基本逻辑是查找具有父节点的任何节点,然后搜索所有叶节点以查找该节点是否是父节点。如果是这样,只需添加节点...

usort($full_menu, function($a, $b){
    return strcmp($a->menu_order, $b->menu_order);
});

foreach ($full_menu as $key=>$menu )   {
    if ( $menu->parent != 0 ) {
        array_walk_recursive($full_menu, function (&$data) use ($menu)   {
            if ( $data->id == $menu->parent)    {
                $data->children[] = $menu;
            }
        });
    }
}

function translate ( &$menu )    {
    foreach ( $menu as &$menuItem )  {
        $out = array(
            'id' => $menuItem->id,
            'text' => $menuItem->title,
            'href' => $menuItem->link,
            'icon' => $menuItem->icon,
            'target' => $menuItem->target,
            'title' => $menuItem->name,
            'order' => $menuItem->menu_order,
            'parent' => $menuItem->parent
        );
        if ( isset($menuItem->children))    {
            $out['children'] = $menuItem->children;
            translate($out['children']);
        }
        $menuItem = $out;
    }
    unset ( $menuItem );
}
translate ($full_menu);
$full_menu = array_filter ( $full_menu, function ($data ) { return $data['parent'] == 0;});

print_r($full_menu);

我最后添加的部分将把元素重新格式化为所需的数组格式,然后过滤掉根菜单,以删除所有已移动的项目。

答案 2 :(得分:-1)

如果要从数组中删除元素,可以使用unset。 例如

unset($mega_menu[4][0]);