简体   繁体   English

PHP:递归迭代多维数组

[英]PHP: recursively iterating over multi-dimensional array

I have a multi-dimensional array that looks something like this:我有一个多维数组,看起来像这样:

Array ( [text] => Level 0-0 => [children] => 
    Array ( 
    [0] => Array ( [text] => Level 1-0 0 => [children] => 
        Array ( 
        [0] => Array ( [text] => Level 2-0 0 => [children] => 
            Array ( 
            [0] => Array ( [text] => Level 3-0 0 ) 
            [1] => Array ( [text] => Level 3-1 0 ) 
            [2] => Array ( [text] => Level 3-2 0 ) 
            [3] => Array ( [text] => Level 3-3 0 ) 
            [4] => Array ( [text] => Level 3-4 0 ) 
            [5] => Array ( [text] => Level 3-5 0 ) ) ) 
        [1] => Array ( [text] => Level 2-1 0 ) 
        [2] => Array ( [text] => Level 2-2 0 => [children] => 
            Array ( 
            [0] => Array ( [text] => Level 3-0 2 ) ) ) 
        [3] => Array ( [text] => Level 2-3 0 ) 
        [4] => Array ( [text] => Level 2-4 0 ) 
        [5] => Array ( [text] => Level 2-5 0 => [children] => 
            Array ( 
            [0] => Array ( [text] => Level 3-0 5 ) 
            [1] => Array ( [text] => Level 3-1 5 ) 
            [2] => Array ( [text] => Level 3-2 5 ) 
            [3] => Array ( [text] => Level 3-3 5 ) 
            [4] => Array ( [text] => Level 3-4 5 ) 
            [5] => Array ( [text] => Level 3-5 5 ) ) ) 
        [6] => Array ( [text] => Level 2-6 0 ) 
        [7] => Array ( [text] => Level 2-7 0 ) 
        [8] => Array ( [text] => Level 2-8 0 ) 
        [9] => Array ( [text] => Level 2-9 0 => [children] => 
            Array ( 
            [0] => Array ( [text] => Level 3-0 9 ) 
            [1] ...
        [10] ...
    [1] ...
Array ( [text] => Level 0-1 => [children] => 
    Array ( 
    [0] => Array ( [text] => Level 1-0 1 => [children] => 
        Array ( 
        [0] => Array ( [text] => Level 2-0 1 => [children] => 
            Array ( 
            [0] => Array ( [text] => Level 3-0 0 ) 
            [1] ...
        [1] ...
    [1] ...
Array ...

And a recursive function that lists out each [text] => Level xx x还有一个递归函数,列出每个[text] => Level xx x

function getTree(array $array) {
    foreach ($array as $key => $value) {
        echo $value['text']."<br>";
        if (!empty($value['children'])) {
            getTree($value['children']);
        }
    }
}

$array = array (...); //array listed above
$tree = getTree($array);
echo $tree;

This gives me a list like this:这给了我一个这样的列表:

Level 0-0
Level 1-0 0
Level 2-0 0
Level 3-0 0
Level 3-1 0
Level 3-2 0
Level 3-3 0
Level 3-4 0
Level 3-5 0
Level 2-1 0
Level 2-2 0
Level 3-0 2
Level 2-3 0
Level 2-4 0
Level 2-5 0
Level 3-0 5
Level 3-1 5
Level 3-2 5
Level 3-3 5
Level 3-4 5
Level 3-5 5
Level 2-6 0
Level 2-7 0
Level 2-8 0
Level 2-9 0
Level 3-0 9
...
...
...
Level 0-1
Level 1-0 1
Level 2-0 1
Level 3-0 0
...
...
...
...

But what I want is the following where each line is indented based on its level:但我想要的是以下内容,其中每一行都根据其级别缩进:

Level 0-0
    Level 1-0 0
        Level 2-0 0
            Level 3-0 0
            Level 3-1 0
            Level 3-2 0
            Level 3-3 0
            Level 3-4 0
            Level 3-5 0
        Level 2-1 0
        Level 2-2 0
            Level 3-0 2
        Level 2-3 0
        Level 2-4 0
        Level 2-5 0
            Level 3-0 5
            Level 3-1 5
            Level 3-2 5
            Level 3-3 5
            Level 3-4 5
            Level 3-5 5
        Level 2-6 0
        Level 2-7 0
        Level 2-8 0
        Level 2-9 0
            Level 3-0 9
            ...
        ...
    ...
Level 0-1
    Level 1-0 1
        Level 2-0 1
            Level 3-0 0
            ...
        ...
    ...
...

How can I accomplish this?我怎样才能做到这一点?

I've thought about including an incrementing $counter and if statements.我已经考虑过包含一个递增的$counterif语句。 Then if (!empty($value['children'])) { $counter++; }然后if (!empty($value['children'])) { $counter++; } if (!empty($value['children'])) { $counter++; } . if (!empty($value['children'])) { $counter++; } . So if counter is 1, add one indent at the beginning of each line.因此,如果 counter 为 1,则在每一行的开头添加一个缩进。 If counter is 2, add two indents, etc. But then I need to decrement $counter-- at the end of every array after iterating over all the children of that array.如果 counter 为 2,则添加两个缩进,等等。但是我需要在遍历该数组的所有子项之后在每个数组的末尾递减$counter-- That's where I'm logically stuck.这就是我在逻辑上陷入困境的地方。 How can I check if an array is the last array in an array?如何检查数组是否是数组中的最后一个数组? if (array is last array)) { $counter--; }

Can this solution work?这个解决方案可以工作吗? Or is there a better solution I'm not thinking of?或者有没有我没有想到的更好的解决方案?

A simple way would be to pass in a padding string, when you call the next level add a tab(or you could add spaces if you wish).一种简单的方法是传入一个填充字符串,当您调用下一级时添加一个制表符(或者您可以根据需要添加空格)。 Then just echo it before your output...然后在你的输出之前回应它......

function getTree(array $array, string $pad = '' ) {
    foreach ($array as $key => $value) {
        echo $pad.$value['text']."<br>";
        if (!empty($value['children'])) {
            getTree($value['children'], $pad."\t");
        }
    }
}

getTree($array);

As your getTree() function doesn't return anything, it's not worth capturing the value and displaying it.由于您的getTree()函数不返回任何内容,因此不值得捕获该值并显示它。

As I mentioned in my comment, it would help if you gave your array in var_export() format.正如我在评论中提到的,如果您以var_export()格式提供数组会有所帮助。 That allows easier testing as with your current sample data it's a pain to convert it to an actual array.这样可以更轻松地进行测试,就像使用当前的样本数据一样,将其转换为实际数组是一件很痛苦的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM