【问题标题】:Loop through nested arrays in PHP循环遍历 PHP 中的嵌套数组
【发布时间】:2020-11-02 19:50:40
【问题描述】:

我有一个非常复杂的数组需要循环。

Array(

  [1] => Array(

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

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

        [1] => ""

      )

    )

  )

)

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

此数组表示 cmets 和回复,其中回复可以包含更多回复。

有什么想法吗?

【问题讨论】:

  • 如果你不知道嵌套的深度,那么你可能需要一个递归函数
  • 写一个递归函数,或者等价的循环:从一个空栈(数组)开始,循环弹出顶部的项目并处理它,同时处理如果你找到任何子数组然后推送它们放到堆栈上。重复直到堆栈为空。
  • 取决于您需要对数据做什么以及是否需要知道它在数组中的位置。你能举一个具体的例子来说明你所追求的结果吗?

标签: php arrays


【解决方案1】:

您可以使用a \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

代码只是为了详细解释您可以看到的内容。迭代器遍历每个级别。你如何实际编码它取决于你。请记住,过滤或展平数组(阅读:预先转换它)可能是另一种选择。您也可以使用生成器并发出每个级别,也可以使用 Cooperative Multitasking/ Coroutines 作为 PHP 核心维护者 nikic 在他的博客文章中解释。

专业提示:使用不同的变体监控您的 RAM 消耗,以防您的嵌套数组确实很大并且可能经常请求或应该快速提供结果。

如果您确实需要快速,请考虑对结果进行流式传输,这样您就可以在处理输入数组的同时处理输出。

最后一个选项可能是将实际数组拆分为块(例如在流式传输时),从而处理较小的部分。

【讨论】:

    【解决方案2】:

    情况相当复杂,因为你have to 循环,但由于某些原因你不能或不想这样做:

    ...我需要循环遍历

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

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

    如果由于某些原因无法选择,您可以考虑:

    • 以某种方式将这个大数组拆分为更小的数组
    • 检查它如何与json_encode 一起工作并使用str_* 函数和正则表达式解析字符串

    您的问题包含太多我们无法确定的内容,例如这些子数组到底包含什么,你能忽略它们的某些部分吗?你能改变首先创建巨大数组的代码吗?

    另一方面,假设您可以循环。有什么可以打扰你的?内存使用情况,需要多长时间等? 您始终可以使用 cron 每天运行它等,但最重要的是首先找到导致您最终获得巨大数组的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      相关资源
      最近更新 更多