在PHP中遍历嵌套数组

3
我有一个非常复杂的数组需要循环遍历。
Array(

  [1] => Array(

    [1] => ""
    [2] => Array(

      [1] => ""
      [2] => Array(

        [1] => ""

      )

    )

  )

)

我不能使用嵌套循环,因为这个数组可能包含数百个嵌套数组。而且,嵌套的数组也可能包含嵌套的数组。

这个数组表示评论和回复,其中回复可能包含更多的回复。

你有什么想法吗?


1
如果您不知道嵌套的深度,那么您可能需要一个递归函数。 - ADyson
2
编写一个递归函数或等效的循环:从一个空栈(数组)开始,循环弹出顶部项并处理它,如果在处理过程中发现任何子数组,则将它们推入栈中。重复此过程直到栈为空。 - Jon
取决于您需要对数据执行什么操作以及是否需要知道它在数组中的位置。您能否给出一个具体的例子,说明您想要的结果是什么。 - Nigel Ren
2个回答

2
您可以使用\RecursiveArrayIterator,它是PHP SPL的一部分,随着PHP核心一起非可选地提供。
<?php

$arr = [
    'lvl1-A' => [
        'lvl2' => [
            'lvl3' => 'done'
        ],
    ],
    'lvl1-B' => 'done',
];

function traverse( \Traversable $it ): void {
    while ( $it->valid() ) {
        $it->hasChildren() 
            ? print "{$it->key()} => \n" and traverse( $it->getChildren() ) 
            : print "{$it->key()} => {$it->current()}\n";
        $it->next();
    }
}

$it = new \RecursiveArrayIterator( $arr );
$it->rewind();
traverse( $it );
print 'Done.';

在REPL中运行并播放此示例:https://3v4l.org/cGtoi 这段代码只是为了详细解释您可以期望看到什么。迭代器遍历每个级别。您实际编码的方式取决于您自己。请记住,过滤或展平数组(即:提前转换它)可能是另一个选项。您也可以使用生成器并发出每个级别,也许可以使用PHP核心维护者nikic在他的博客文章中解释的协作多任务/协程
专业提示:如果您的嵌套数组确实很大,并且可能经常请求或需要快速提供结果,请使用不同的变体监视RAM消耗。
如果您真的需要快速,请考虑流式传输结果,以便在处理输入数组时仍然可以处理输出。
最后一个选择可能是将实际数组分成块(例如在流式传输它们时),因此处理更小的部分。

1
这个案例非常复杂,因为你需要循环,但出于某些原因,你可能无法或不想循环:

...我需要遍历

我不能使用嵌套循环,因为这个数组可能包含数百个嵌套数组

这意味着您必须以不同的方式处理数据,因为您可以将大量要处理的数据打包以备后续处理。

如果由于某些原因这不是一个选项,您可以考虑:

  • 将此大型数组分成较小的数组
  • 检查如何使用 json_encode 以及使用 str_* 函数和正则表达式解析字符串

您的问题包含太多我们无法确定的事情,例如这些子数组究竟包含什么,是否可以忽略它们的某些部分,是否可以更改创建巨大数组的代码等等。

另一方面,假设您可以循环。会有什么困扰吗?内存使用情况,需要多长时间等等? 您始终可以使用 cron 在每天运行等,但最重要的是找到为什么首先会出现巨大数组的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接