【问题标题】:Recursive function not iterating variable as expected递归函数未按预期迭代变量
【发布时间】:2018-09-03 01:10:20
【问题描述】:

当我遇到一些意外行为时,我目前正在重写一个按大小排序的导航结构,我已在此处成功重新创建。

我正在创建一个包含多个项目的数组,也是数组。这些项目包含一个名称,并且可能包含一个数组sub,它是一个包含更多项目的数组。这有可能嵌套到无穷大。 该列表将以 HTML 格式显示为多层ul。 在这种情况下,使用递归函数是有意义的。如前所述,列表稍后将按大小排序,因此我创建了变量$index,它应该计算当前列表中的项目总数,而不是在完成一个级别后继续计算 PHP决定在函数被递归打开之前使用之前的迭代。

下面的代码、输出和扩展输出。

我的问题:有没有办法在整个函数中迭代变量$index

PHP 代码:

<!-- language: php -->
<?php
$lists = [
    [
        'name' => 'level0-item',
        'sub' => [
            ['name' => 'level1-item'],
            ['name' => 'level1-item'],
            ['name' => 'level1-item'],
            [
                'name' => 'level1-item',
                'sub' => [
                    ['name' => 'level2-item'],
                    ['name' => 'level2-item'],
                ]
            ],
            [
                'name' => 'level1-item',
                'sub' => [
                    ['name' => 'level2-item'],
                    ['name' => 'level2-item'],
                ]
            ],
        ]
    ],

    [
        'name' => 'level0-item',
        'sub' => [
            ['name' => 'level1-item'],
            ['name' => 'level1-item'],
            ['name' => 'level1-item'],
        ]
    ]
];

function handleLists($lists, $index = 0, $level = 0) {
    echo '<ul>';
    foreach ($lists as $list) {
        echo '<li>';
        $index++; // increas index
        echo $list['name'] . ' - level: ' . $level . ' - index: ' . $index;

        if ($list['sub'])
            handleLists($list['sub'], $index, $level+1); // recursive call
        echo '</li>';
    }
    echo '</ul>';
}

handleLists($lists);
?>

输出:

  • level0-item - 级别:0 - 索引:1
    • level1-item - 级别:1 - 索引:2
    • level1-item - 级别:1 - 索引:3
    • level1-item - 级别:1 - 索引:4
    • level1-item - 级别:1 - 索引:5
      • level2-item - 级别:2 - 索引:6
      • level2-item - 级别:2 - 索引:7
    • level1-item - 级别:1 - 索引:6
      • level2-item - 级别:2 - 索引:7
      • level2-item - 级别:2 - 索引:8
  • level0-item - 级别:0 - 索引:2
    • level1-item - 级别:1 - 索引:3
    • level1-item - 级别:1 - 索引:4
    • level1-item - 级别:1 - 索引:5

预期输出:

  • level0-item - 级别:0 - 索引:1
    • level1-item - 级别:1 - 索引:2
    • level1-item - 级别:1 - 索引:3
    • level1-item - 级别:1 - 索引:4
    • level1-item - 级别:1 - 索引:5
      • level2-item - 级别:2 - 索引:6
      • level2-item - 级别:2 - 索引:7
    • level1-item - 级别:1 - 索引:8
      • level2-item - 级别:2 - 索引:9
      • level2-item - 级别:2 - 索引:10
  • level0-item - 级别:0 - 索引:11
    • level1-item - 级别:1 - 索引:12
    • level1-item - 级别:1 - 索引:13
    • level1-item - 级别:1 - 索引:14

加法

我可能错误地理解了嵌套的 foreach-/for-loops,这里有一些希望可以理解的伪代码,每次打开新的 foreach 时,我都会增加 1。

预期行为:

i = 0

// 第一步
foreach1 打开 i = 1

// 第二步
foreach1
__foreach2 打开 i = 2

// 第三步
foreach1
__foreach2
foreach1 打开 i = 3

// 第四步
foreach1
__foreach2
foreach1
__foreach2 打开 i = 4

明显的行为:

i = 0

// 第一步
foreach1 打开 i = 1

// 第二步
foreach1
foreach1 打开 i = 2

// 第三步
foreach1
__foreach2 打开 i = 2(导致之前的 foreach1 i = 1)
foreach1

// 第四步
foreach1
__foreach2
foreach1
__foreach2 打开 i = 3(导致之前的 foreach1 i = 2)

【问题讨论】:

  • 你的问题和例子很难理解。你能举一个更小的例子吗?对我来说,您的输出与预期输出相同。见stackoverflow.com/help/mcve
  • 我的回答对你有帮助吗?
  • @Andreas 实际上我已经将我的代码减少了很多,以便于理解。但我强调了输出中的差异。

标签: php loops foreach iteration


【解决方案1】:

如果您想在整个树中跟踪 $index 的实际值,则可以将其传递给 handleLists 作为参考 (&amp;index) 而不是值:

function handleLists($lists, &$index = 0, $level = 0) { 
....
}

这样,当您在递归调用(级别 1)中并递增 $index 时,该索引也会在第一级(级别 0)上递增,因为当您进入更深的级别时,它是同一个变量。

希望这会有所帮助。

【讨论】:

  • 就这在简化的 PHP 示例中确实有效,我还没有找到一种方法可以在我正在扩展的 Smarty 模板中使其工作,如果很快没有更好的答案弹出我'一定会接受你的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 2018-12-05
  • 1970-01-01
  • 2019-03-01
  • 2011-11-30
  • 1970-01-01
  • 2019-04-03
相关资源
最近更新 更多