递归树遍历 - 如何跟踪递归级别?

Bog*_*dan 7 php recursion

我基本上试图从表示树结构的多维数组构建一个html ul/li嵌套列表.

以下代码工作正常,但我想改进它:

我需要一种方法来跟踪递归级别,以便我可以将不同的类应用于不同的级别,为生成的输出添加缩进等.

function buildTree($tree_array, $display_field, $children_field, $class='', $id='') {

  echo "<ul>\n";

  foreach ($tree_array as $row) {

    echo "<li>\n";
    echo $row[$display_field] . "\n";

    if (isset($row[$children_field])) {

      $this->buildTree($row[$children_field]);
    }
    echo "</li>\n";
  }
  echo "</ul>\n";
} 
Run Code Online (Sandbox Code Playgroud)

$ tree_array如下所示:

Array
(
    [0] => Array
        (
            [category_id] => 1
            [category_name] => calculatoare
            [parent_id] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [category_id] => 4
                            [category_name] => placi de baza
                            [parent_id] => 1
                        )

                    [1] => Array
                        (
                            [category_id] => 5
                            [category_name] => carcase
                            [parent_id] => 1
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [category_id] => 6
                                            [category_name] => midi-tower
                                            [parent_id] => 5
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [category_id] => 2
            [category_name] => electronice
            [parent_id] => 0
        )

    [2] => Array
        (
            [category_id] => 3
            [category_name] => carti
            [parent_id] => 0
        )

)
Run Code Online (Sandbox Code Playgroud)

我把它标记为家庭作业,因为我想用这个机会来改善我对递归的理解(差),所以,我很感激能够指导我解决问题的答案,而不是提供一个完整的工作示例: )

vzw*_*ick 9

Quick'n'dirty方法(请参阅下面的"扰流器"块以实现):

$recursionDepth在函数声明中添加一个附加变量,默认为0.

在每次后续递归中,使用调用函数0.

由于函数变量仅对函数的相应实例"可见"(作用域),因此最终会得到当前迭代深度的指示符.

另外,你的功能的第12行

$this->buildTree();
Run Code Online (Sandbox Code Playgroud)

我不认为它会起作用 - 原因是你没有将变量传递给buildTree的下一个实例.

它可能看起来像这样:

$this->buildTree($row[$children_field], $display_field, $children_field, $class, $id)
Run Code Online (Sandbox Code Playgroud)

以下是我为您的代码所做的更改,以实现您的目标:

function buildTree($tree_array, $display_field, $children_field, $class='', $id='', $recursionDepth = 0, $maxDepth = false)
{
    if ($maxDepth && ($recursionDepth == $maxDepth)) return;

    echo "<ul>\n";

    foreach ($tree_array as $row)
    {
        echo "<li>\n";
        echo $row[$display_field] . "\n";

        if (isset($row[$children_field]))
            $this->buildTree($row[$children_field], $display_field, $children_field, $class, $id, $recursionDepth + 1, $maxDepth);

        echo "</li>\n";
    }
    echo "</ul>\n";
}
Run Code Online (Sandbox Code Playgroud)


Gor*_*don 8

你正在使你的生活变得比它需要的更困难.该SPL提供了大量的迭代器为您提供方便.在RecursiveArrayIterator课堂上遍历多维数组很容易.它不仅允许您处理任何级别深度数组,而且还可以跟踪深度.

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array)
);

for($iterator; $iterator->valid(); $iterator->next())
{
    printf(
        "Key: %s Value: %s Depth: %s\n",
        $iterator->key(),
        $iterator->current(),
        $iterator->getDepth()
    );
}
Run Code Online (Sandbox Code Playgroud)

键盘上的示例

如您所见,有一种方法getDepth()可以始终告诉您当前的迭代深度.这是RecursiveIteratorIterator在递归迭代器中迭代子节点所需的方法.

如果您需要影响迭代开始时或访问子项时发生的事情,请查看我对Multidimensional数组迭代的回答,该回答显示了一个自定义RecursiveIteratorIterator,它将多维数组的值包装到xml元素中并按深度缩进它们.当前迭代(应该很容易适应ul/li元素).

另请参阅有关迭代器维基百科文章,以获得一般性介绍.