PHP - 从阵列
我试图创建一个“插件”之类的脚本添加到“菜单阵” ......我会去直接在导航/ subnav结构..PHP - 从阵列
可以说我发起导航项目如下:
$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
));
首先创建一个新的部分并获取实例。
然后,我们设置一个“角色”,我们将在其中测试以查看用户是否已通过身份验证以查看。
设置导航项只存储数组。标识符是对项目的引用(当我们想要添加子项目时),除了“位置”之外的所有标准,它说明它位于nav中的位置,即NULL是顶层,数组('topnav','subnav ')将是topnav-> subnav->仪表板。
的测试,这可以存储如下:
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] =>
)
)
)
)
这是我对问题的看法,用递归解决。
你可以使用多个职位(我猜这就是为什么它是一个数组),如果至少有一个职位被发现,它会忽略缺少的职位,但是如果每个职位都没有,就会抱怨。
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);
在它的当前形式不一旦被放置在距离阵列节点移除identifier
或position
密钥。
似乎无法得到这个正常工作,不断把所有东西作为仪表板的直接子... http://pastebin.com/uWuX0QeU – 2012-08-16 20:26:16
哦,我错误地解释了'position'数组的含义(基于在原始问题上)。有了这个版本,你不必一路列出每一个父母,只有最近的一个(在我的例子中,'thirdlevelchild'只有'secondlevelchild2'的位置,get的放置正确)。但是有了完整的路径,它也可以更容易地完成( - : – complex857 2012-08-16 20:30:53
啊,我看到是的。原来的“位置”映射数组值的路径,但你的方式增加了多个...认为这可能更好! AHA!天才,谢谢你们两位! – 2012-08-16 20:32:44
您需要一个临时数组,将标识符映射到它的子数组,以便您可以将它添加到那里。
如果我看到正确的,你有类似的东西已经在这里当你添加父:
$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')'的部分...所以密钥不会设置在临时数组中...... – 2012-08-16 19:09:40
I知道你已经花了上面的时间,但我不知道这将如何工作......让我创建一个数据,我在我的脑海中看到,这将导致问题的数组... – 2012-08-16 19:16:56
我已经添加了一个数据结构这个问题... – 2012-08-16 19:30:51
[嵌套数组可能重复。第三级消失](http://*.com/questions/7673044/nested-array-third-level-is-disappearing) – hakre 2012-08-16 20:55:03