Php 在多维数组中查找特定ID的路径
我有一个存储如下的数组:Php 在多维数组中查找特定ID的路径,php,arrays,path-finding,Php,Arrays,Path Finding,我有一个存储如下的数组: [0] => Array ( [id] => 1 [cat_name] => c1 ) [1] => Array ( [id] => 2 [cat_name] => c2 [copii] => Array ( [0] => Array
[0] => Array
(
[id] => 1
[cat_name] => c1
)
[1] => Array
(
[id] => 2
[cat_name] => c2
[copii] => Array
(
[0] => Array
(
[id] => 5
[cat_name] => c21
)
[1] => Array
(
[id] => 6
[cat_name] => c22
)
)
)
[2] => Array
(
[id] => 3
[cat_name] => c3
[copii] => Array
(
[0] => Array
(
[id] => 7
[cat_name] => c31
[copii] => Array
(
[0] => Array
(
[id] => 9
[cat_name] => c311
)
)
)
[1] => Array
(
[id] => 8
[cat_name] => c32
)
)
)
我正试图找到一种更简单的方法找到通往某个ID的路线。
现在我使用foreach遍历所有可能的数组并找到路由
例如:
id = 1:
route[0][id]=1,route[0][cat_name]=c1
id = 5:
route[0][id]=2,route[0][cat_name]=c2
route[1][id]=5,route[1][cat_name]=c21
id = 9:
route[0][id]=3,route[0][cat_name]=c3
route[1][id]=7,route[1][cat_name]=c31
route[2][id]=9,route[2][cat_name]=c311
如果我的问题没有意义,我会把它归咎于花了多少时间试图找到一个好的解决方案……你的问题确实没有意义。“找到路线”是什么意思
看起来您的数组具有描述图形的递归结构;用于查找最短路径的图形遍历算法可能更合适(即,将数组转换为图形数据结构-可能是节点列表+边列表,并在其上运行图形算法) 如果您不知道递归,我建议您阅读递归,而不是发布一堆代码。PHP在递归方面不是很好,但它确实是您唯一的选择 基本上,您需要调用一个函数,该函数接受数组、要查找的id和表示路径的字符串/数组。最初使用空字符串或空数组调用后一个参数 在函数中,您可以执行以下操作:
- 在
$array
- 如果找到要查找的
,请返回$id
$path
- 如果其中一个数组值是子数组,则添加当前ID节点并使用该节点再次调用函数-类似于
$foundPath=findPath($array,$ID,$path)
- 如果
返回了一些内容,那么您已经获得了路径并可以返回$foundPath
- 如果它没有找到任何东西(
如下所示为false或null),请保留它并继续循环的下一次迭代$foundPath
- 在循环结束时,如果没有找到任何内容,则返回false或null
希望有帮助 递归是您想要的:
<?php
function walk_array(array $a, &$ra, $path, $depth = 0) {
$id= isset($path[$depth]) ? $path[$depth] : null;
if (!is_null($id)) {
foreach ($a as $a2) {
if ($a2['id'] == $id) {
$ra[$depth]= $a2;
unset($ra[$depth]['copii']);
// This is the key bit - recursion is simply a function calling itself:
if (isset($a2['copii']))
walk_array($a2['copii'], $ra, $path, ++$depth);
}
}
}
}
$complex_array= array(
array('id'=> 1, 'name'=> 'Node #1', 'copii'=> array(
array('id'=> 3, 'name'=> 'Node #3', 'copii'=> array(
array('id'=> 4, 'name'=> 'Node #4')
))
)),
array('id'=> 2, 'name'=> 'Node #2', 'copii'=> array(
array('id'=> 5, 'name'=> 'Node #5', 'copii'=> array(
array('id'=> 6, 'name'=> 'Node #6',)
))
)),
);
// Prints out nodes 1,3,4 in order
$ra= array();
walk_array($complex_array, $ra, array(1, 3, 4));
print_r($ra);
// Prints out nodes 2,5,6 in order
$ra= array();
walk_array($complex_array, $ra, array(2, 5, 6));
print_r($ra);
// Prints out empty array
$ra= array();
walk_array($complex_array, $ra, array(5, 2, 4));
print_r($ra);
// Prints out nodes 2,5 in order
$ra= array();
walk_array($complex_array, $ra, array(2, 5));
print_r($ra);
?>
我能想到的另一种方法——避免递归——是使用“变量变量”,因此您只需在一定程度上尝试数组索引的所有可能组合
$search = 3;
$ind = '$arr[0][copii][1]'; // generated somehow
if ( isset(${$ind}['id']) && ${$ind}['id'] == $search ) {
// we found it
}
这将花费同样长的时间,而且你不能保证找到任何东西。在我写这篇文章的时候,我还在努力想一个可靠的方法来生成$ind
值。。。除了递归。我想你可以生成3位数字,比如000、001、002,然后使用每个字符创建索引,比如$arr[0][copii][0][copii][0]
,$arr[0][copii][0][copii][1]
和$arr[0][copii][2]
这种方法仍然不完美,因为毫无疑问,您将错过值,并寻找许多不存在的值。老实说,递归在代码方面是更简单、更干净的选项,除非你的数组有数百个条目,否则你不会注意到一个大的性能问题。我知道递归,但据我在php中看到的,它不是最好的解决方案,这就是为什么我试图避免它我试图避免递归算法,我知道他们,用过他们,但我正试图得到一个迭代的解决方案。。。如果我不能,那么我只能使用递归,但这不是我的第一个选择如果数组的深度未知,那么递归是我所知的唯一解决方案。即使递归的深度不超过3个数组,它仍然比几个嵌套循环更干净。它的最大深度为3,我现在正在测试递归和迭代解决方案的效率。。。今天晚些时候,我将用解决方案更新这个问题。在这种情况下,您可以使用3个嵌套for循环,并检查每个循环是否有copii子数组,例如:
if(isset($arr[$i]['copii']){for(…)}
是的,它的结构有点像一个图,但我试图避免更改结构