dongzhent208577 2012-08-16 18:54
浏览 26
已采纳

php - 数组中的nav / subnav结构

I'm trying to create a "plugin" like script for adding to a "menu array".... I'll go straight in..

Lets say I initiate a nav item like so:

$sections->add_section('dashboard');
$DashBoardSection = $sections->load_section('dashboard');
$DashBoardSection->set_role(NULL);
$DashBoardSection->set_nav_item(array(
    'identifier' => 'dashboard',
    'text' => 'Dashboard',
    'url' => NULL,
    'position' => NULL
));

starts off by creating a new section and the getting the instance of.

We are then setting a "role" in which we will test against to see if the user is authenticated as being verified to view.

The set nav item simply stores the array. identifier is a reference to the item ( its for when we want to add sub items), all standard apart from "position" which states where it is to sit in the nav i.e. NULL is top level, array('topnav','subnav') will be topnav->subnav->dashboard.

as a test, this could be stored as follows:

Array
(
    [0] => Array
        (
            [identifier] => dashboard
            [text] => Dashboard
            [url] => 
            [position] => 
        )
[1] => Array
    (
        [identifier] => dashboard2
        [text] => Dashboard2
        [url] => 
        [position] => Array
            (
                [0] => dashboard
            )

    )

)

my question being how I turn that into the following structure:

Array
(
    [0] => Array
    (
        [identifier] => dashboard
        [text] => Dashboard
        [url] => 
        [position] => 
        [children] => Array
            (
                [0] => Array
                    (
                        [identifier] => dashboard2
                        [text] => Dashboard2
                        [url] => 
                    )
            )
    )
)

pulling my hair out over this one, any help would be very much appreciated.

regards

I currently have

public function build_navigation( $role ){
    $role = (int)$role;
    $nav  = array();
    foreach( $this->sections as $section ) {
        if( $section->get_role() === NULL || $section->get_role() === $role ) {
            $nav_array = $section->get_nav();
            foreach( $nav_array as $key => $nav_item ) {
                if( $nav_item['position'] === NULL ) {
                    $nav[$nav_item['identifier']] = $nav_item;
                }elseif( is_array( $nav_item['position'] ) ){
                    #...#
                }
            }
        }
    }
    return $nav;
}

EDIT

Imagine this is the array given (it can be in any order)

Array
(
    [0] => Array
        (
            [identifier] => dashboard_child2
            [text] => Dashboard Child 2
            [url] => 
            [position] => Array
                (
                    [0] => dashboard
                )

        )

    [1] => Array
        (
            [identifier] => dashboard_child_child_1
            [text] => Dashboard Child Child 1
            [url] => 
            [position] => Array
                (
                    [0] => dashboard
                    [1] => dashboard_child1
                )

        )



[2] => Array
    (
        [identifier] => dashboard_child1
        [text] => Dashboard Child 1
        [url] => 
        [position] => Array
            (
                [0] => dashboard
            )

    )

[3] => Array
    (
        [identifier] => dashboard
        [text] => Dashboard
        [url] => 
        [position] => 
    )

[4] => Array
    (
        [identifier] => dashboard2
        [text] => Dashboard2
        [url] => 
        [position] => Array
            (
                [0] => dashboard
            )

    )

)

Which needs to be formatted as:

Array
(
    [dashboard] => Array
        (
            [text] => Dashboard
            [url] => 
            [children] => Array
                (
                    [dashboard_child2] => Array
                        (
                            [text] => Dashboard Child 2
                            [url] => 
                        )
                    [dashboard_child1] => Array
                        (
                            [text] => Dashboard Child 1
                            [url] => 
                            [children] => Array
                                (
                                    [dashboard_child_child_1] => Array
                                        (
                                            [text] => Dashboard Child Child 1
                                            [url] => 
                                        )
                                )
                        )
                    [dashboard2] => Array
                        (
                            [text] => Dashboard2
                            [url] =>
                        )
                )
        )
) 
  • 写回答

2条回答 默认 最新

  • doulai6469 2012-08-16 20:03
    关注

    Here's my take on the problem, solved with recursion.

    You can use multiple positions (i guess this is why it's an array), it will ignore missing positions if at least on of the positions is found, but will complain if every position is missing.

    function translate($in) {
    
        $out = array();
    
        // first pass, move root nodes to output
        foreach ($in as $k => $row) {
            if (!$row['position']) {
                $out[$row['identifier']] = $row;
                unset($in[$k]);
            }
        }
    
        // while we have input
        do {
            $elements_placed = 0;
            // step trough input
            foreach ($in as $row_index => $row) {
                foreach ($row['position'] as $pos) {
                    // build context for the node placing
                    $data = array(
                        'row' => $row,
                        'in'  => &$in,
                        'row_index' => $row_index,
                        'elements_placed' => &$elements_placed,
                        'pos' => $pos,
                    );
                    // kick of recursion
                    walker($out, $data);
                }
            }
        } while ($elements_placed != 0);
        if (count($in)) {
            trigger_error("Error in user data, can't place every item");
        }
        return $out;
    }
    
    function walker(&$out, $data) {
        foreach ($out as &$row) {
            // it looks like a node array
            if (is_array($row) && isset($row['identifier'])) {
                // if it has children recurse in there too
                if (isset($row['children'])) {
                    walker($row['children'], $data);
                }
    
                // it looks like a node array that we are looking for place the row
                if ($row['identifier'] == $data['pos']) {
                    if (!isset($row['children'])) {
                        $row['children'] = array($data['row']['identifier'] => $data['row']);
                    } else {
                        $row['children'][$data['row']['identifier']] = $data['row'];
                    }
                    // report back to the solver that we found a place
                    ++$data['elements_placed'];
                    // remove the row from the $in array
                    unset($data['in'][$data['row_index']]);
                }
            }
        }
    }
    
    $in = array (
        array (
            'identifier' => 'secondlevelchild2',
            'text' => 'secondlevelchild2',
            'url' => '',
            'position' => array (
                'dashboard2',
            ),
        ),
        array (
            'identifier' => 'secondlevelchild',
            'text' => 'secondlevelchild',
            'url' => '',
            'position' => array (
                'dashboard2',
            ),
        ),
        array (
            'identifier' => 'dashboard',
            'text' => 'Dashboard',
            'url' => '',
            'position' => '',
        ),
        array (
            'identifier' => 'dashboard2',
            'text' => 'Dashboard2',
            'url' => '',
            'position' => array (
                'dashboard', 'home',
            ),
        ),
        array (
            'identifier' => 'thirdlevelchild',
            'text' => 'thirdlevelchild',
            'url' => '',
            'position' => array (
                'secondlevelchild2',
            ),
        ),
    );
    
    $out = translate($in);
    var_export($out);
    

    In it's current form it doesn't remove the identifier or position keys from the node arrays once they are placed.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单