1

我有一个这样存储的数组:

[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

如果我的问题没有意义,我将其归咎于试图找到一个好的解决方案所花费的时间......

4

4 回答 4

1

代替发布一堆代码,如果您不了解递归,我建议您阅读递归。PHP 在递归方面不是很好,但它确实是您唯一的选择。

基本上,您会调用一个函数,该函数接受数组、要查找的 id 以及表示路径的字符串/数组。最初使用后一个参数的空白字符串或空数组调用它。

在函数中你会这样做:

  • 通过顶层运行 foreach$array
  • 如果你找到$id你要找的,返回$path.
  • 如果其中一个数组值是子数组,则添加当前 ID 节点并再次调用该函数 - 类似于$foundPath = findPath( $array, $id, $path ).
  • 如果$foundPath返回一些东西,那么你就有了你的路径并且可以返回。
  • 如果它没有找到任何东西($foundPath如下所示为 false 或 null),则离开它并继续循环的下一次迭代。
  • 在循环结束时,如果您没有找到任何内容,则返回 false 或 null。

希望有帮助!

于 2009-12-02T09:23:53.627 回答
1

递归是你想要的:

<?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);
?>
于 2009-12-02T09:30:25.813 回答
0

你的问题确实没有意义。“寻找路线”是什么意思?

看起来您的数组具有描述图形的递归结构;用于查找最短路径的图遍历算法可能更合适(即将您的数组转换为图数据结构 - 可能是节点列表 + 边列表,并在其上运行图算法)。

于 2009-12-02T09:14:34.767 回答
0

我能想到的另一种方法 - 避免递归 - 是使用“变量变量”,所以你只需尝试数组索引的所有可能组合,直到某一点。

$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][0][copii][2].

这种方法仍然不完美,因为您无疑会错过值并寻找许多不存在的值。老实说,递归在代码方面是更简单、更清晰的选项,除非你的数组有数百个条目,否则你不会注意到一个大的性能问题。

于 2009-12-03T17:17:18.987 回答