【问题标题】:php - nav/subnav structure from arrayphp - 来自数组的导航/子导航结构
【发布时间】:2012-08-16 18:54:20
【问题描述】:

我正在尝试创建一个类似于脚本的“插件”,用于添加到“菜单数组”中......我会直接进入......

假设我像这样启动一个导航项:

$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
));

首先创建一个新部分并获取其实例。

然后,我们将设置一个“角色”,我们将在其中进行测试,以查看用户是否经过身份验证,可以查看。

set nav 项只是存储数组。标识符是对项目的引用(它用于我们想要添加子项目时),除了“位置”之外的所有标准,它说明它在导航中的位置,即 NULL 是顶级,array('topnav','subnav ') 将是 topnav->subnav->dashboard.

作为测试,这可以存储如下:

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

    )

)

我的问题是如何将其转换为以下结构:

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

把我的头发拉到这个上面,非常感谢任何帮助。

问候

我现在有

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;
}

编辑

想象这是给定的数组(可以是任何顺序)

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
            )

    )

)

需要格式化为:

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] =>
                        )
                )
        )
) 

【问题讨论】:

标签: php arrays navigation


【解决方案1】:

这是我对这个问题的看法,通过递归解决。

你可以使用多个位置(我想这就是为什么它是一个数组),如果找到至少一个位置,它将忽略丢失的位置,但如果每个位置都丢失了,它会抱怨。

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);

在当前形式中,一旦放置了节点数组,它就不会从节点数组中删除 identifierposition 键。

【讨论】:

  • 似乎无法使其正常工作,一直将所有内容作为仪表板的直接子项...pastebin.com/uWuX0QeU
  • 哦,我误解了position 数组的含义(基于原始问题)。使用此版本,您不必沿途仅列出最近的每个父级(在我的示例数据中,thirdlevelchild 只有一个secondlevelchild2 位置并且正确放置)。但是,有了可用的完整路径,它也可以更轻松地完成(-:
  • 啊,我明白了。原始的“位置”映射了数组值中的路径,但您的方式增加了不止一个......认为这可能更好!啊哈!天才。谢谢你们!
【解决方案2】:

您需要一个临时数组,将标识符映射到它的子数组,以便您可以将其添加到那里。

如果我没看错,当你添加父级时,你已经有类似的东西了:

$nav[$nav_item['identifier']] = $nav_item;

编辑:如评论中所指出的,添加父级需要谨慎:

$node = &$nav[$nav_item['identifier']];
$children = isset($node['children']) ? $node['children'] : array();
$node = $nav_item;
$node['children'] = $children;
unset($node);

然后添加到孩子:

foreach($nav_item['position'] as $identifier)
{
    $nav[$identifier]['children'][] = $nav_item;
}

你也可以使用对象,而不是数组,这样你就不会复制太多数据(或者你可以稍后更改它),但是,只是想,这对于解决你的问题不一定是必要的,所以可能以后再说。

【讨论】:

  • 那是我的问题...如果将其设置为插件范围/环境,则没有理由在标识符“foo”或“bar”之前读取位置为array('foo','bar','foobar') 的部分...所以不会在临时数组中设置密钥...
  • 我知道你已经花时间在上面,但我看不出这是如何工作的......让我创建一个我在脑海中看到的数据数组,这将导致问题...... .
  • @PhilJackson:简单的方法在这里概述:Converting an array from one to multi-dimensional based on parent ID valuesNested array. Third level is disappearing- 我不知道你在寻找一棵树。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 2020-02-07
  • 2021-07-24
  • 1970-01-01
相关资源
最近更新 更多