我正在研究导航结构。 我正在使用父模型,所以我将所有子导航节点放入一个数组并将它们附加到父导航。
数组结构如下所示:
$navigation = array(
0 =>
array(
'id' => '2',
'parent_id' => '0',
'name' => 'abouts us',
'subNavigation' =>
array(
0 => array(
'id' => '3',
'parent_id' => '2',
'name' => 'Foo',
'subNavigation' =>
array(
0 => array(
'id' => '4',
'parent_id' => '3',
'name' => 'test',
'subNavigation' =>
array(),
),
1 => array(
'id' => '5',
'parent_id' => '3',
'name' => 'bar',
'subNavigation' =>
array(),
),
),
),
),
),
1 =>
array(
'id' => '6',
'parent_id' => '0',
'name' => 'Foobar',
'subNavigation' =>
array(
0 => array(
'id' => '7',
'parent_id' => '6',
'name' => 'ASDF',
'subNavigation' =>
array(),
),
),
),
);
现在我想搜索一个导航ID,例如ID = 5(Navigation-Name = bar),结果应该是这个子导航的数组。
结果:
$result = array(
0 =>
array(
'id' => '2',
'parent_id' => '0',
'name' => 'abouts us',
'subNavigation' =>
array(
0 => array(
'id' => '3',
'parent_id' => '2',
'name' => 'Foo',
'subNavigation' =>
array(
0 => array(
'id' => '5',
'parent_id' => '3',
'name' => 'bar',
'subNavigation' =>
array(),
),
),
),
),
),
);
最快的方式是什么,递归函数将完成这项工作?
编辑: 我编辑导航节点5的parent_id ...其中是一个错误的parent_id
答案 0 :(得分:1)
非常有趣的问题。这是一个解决方案:
function search($navitation_tree, $id, $temp_branch = array()) {
for ($i = 0; $i < sizeof($navitation_tree); $i++) {
$nav_element = $navitation_tree[$i];
if($nav_element['parent_id'] === '0') {
$temp_branch = array();
} else if($i > 0) {
for ($y = 0; $y < 1; $y++) {
array_pop($temp_branch);
}
}
$cloned_nav_element = array('id' => $nav_element['id'],
'parent_id' => $nav_element['parent_id'],
'name' => $nav_element['name'],
'subNavigation' => array());
$temp_branch[] = $cloned_nav_element;
if($nav_element['id'] === $id) {
return $temp_branch;
}
if(sizeof($nav_element['subNavigation'] > 0)) {
$result = search($nav_element['subNavigation'], $id, $temp_branch);
}
if($result != null) {
return $result;
}
}
}
function getNavigationBranch($navitation_tree, $id) {
$branch = search($navitation_tree, $id);
if($branch !== null) {
$final_nav_element = array();
foreach($branch as $temp_nav_element) {
if(empty($final_nav_element)) {
$final_nav_element = array(array_pop($branch));
} else {
$temp_nav_element = array_pop($branch);
$temp_nav_element['subNavigation'] = $final_nav_element;
$final_nav_element = array($temp_nav_element);
}
}
return $final_nav_element;
}
}
$result = getNavigationBranch($navigation, '5');
search
函数在导航树中执行depth-first search(DFS)。一旦找到所需的id,它就会将路径(由有序的导航元素数组表示)返回到getNavigationBranch
,它会将数据重新构造为您在问题中请求的格式,并返回它们(如果找不到id,它将返回null
。
顺便说一句,尽管在大型图表中搜索时DFS可能会出现问题,但我认为它在导航树的大多数情况下都能正常工作(如果不是全部的话)。
为了测试它,我使用了以下数据:
$navigation = array(
0 =>
array(
'id' => '2',
'parent_id' => '0',
'name' => 'abouts us',
'subNavigation' =>
array(
0 => array(
'id' => '3',
'parent_id' => '2',
'name' => 'Foo',
'subNavigation' =>
array(
0 => array(
'id' => '4',
'parent_id' => '3',
'name' => 'test',
'subNavigation' =>
array(),
),
1 => array(
'id' => '5',
'parent_id' => '3',
'name' => 'bar',
'subNavigation' =>
array(),
),
),
),
1 => array(
'id' => '8',
'parent_id' => '2',
'name' => 'Foo',
'subNavigation' =>
array(
0 => array(
'id' => '9',
'parent_id' => '8',
'name' => 'test',
'subNavigation' =>
array(),
),
1 => array(
'id' => '10',
'parent_id' => '8',
'name' => 'bar',
'subNavigation' =>
array(),
),
),
),
2 => array(
'id' => '11',
'parent_id' => '2',
'name' => 'Foo',
'subNavigation' =>
array(
0 => array(
'id' => '12',
'parent_id' => '8',
'name' => 'test',
'subNavigation' =>
array(),
),
1 => array(
'id' => '13',
'parent_id' => '8',
'name' => 'bar',
'subNavigation' =>
array(),
),
),
),
),
),
1 =>
array(
'id' => '6',
'parent_id' => '0',
'name' => 'Foobar',
'subNavigation' =>
array(
0 => array(
'id' => '7',
'parent_id' => '6',
'name' => 'ASDF',
'subNavigation' =>
array(),
),
),
),
);
以下是一些测试结果:
$result = getNavigationBranch($navigation, '5');
var_dump($result);
以上产生:
array(1) {
[0]=>
array(4) {
["id"]=>
string(1) "2"
["parent_id"]=>
string(1) "0"
["name"]=>
string(9) "abouts us"
["subNavigation"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
string(1) "3"
["parent_id"]=>
string(1) "2"
["name"]=>
string(3) "Foo"
["subNavigation"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
string(1) "5"
["parent_id"]=>
string(1) "3"
["name"]=>
string(3) "bar"
["subNavigation"]=>
array(0) {
}
}
}
}
}
}
}
还有一个:
$result = getNavigationBranch($navigation, '13');
var_dump($result);
以上产生:
array(1) {
[0]=>
array(4) {
["id"]=>
string(1) "2"
["parent_id"]=>
string(1) "0"
["name"]=>
string(9) "abouts us"
["subNavigation"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
string(2) "11"
["parent_id"]=>
string(1) "2"
["name"]=>
string(3) "Foo"
["subNavigation"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
string(2) "13"
["parent_id"]=>
string(1) "8"
["name"]=>
string(3) "bar"
["subNavigation"]=>
array(0) {
}
}
}
}
}
}
}