简体   繁体   English

循环遍历 PHP 中的嵌套数组

[英]Loop through nested arrays in PHP

I have a very complex array that I need to loop through.我有一个非常复杂的数组,需要循环遍历。

Array(

  [1] => Array(

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

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

        [1] => ""

      )

    )

  )

)

I can't use nested loops because this array could contain hundreds of nested arrays.我不能使用嵌套循环,因为这个数组可能包含数百个嵌套数组。 Also, the nested ones could contain nested arrays too.此外,嵌套数组也可以包含嵌套数组。

This array presents comments and replies, Where replies could contain more replies.此数组显示评论和回复,其中回复可以包含更多回复。

Any thoughts?有什么想法吗?

You could use a \\RecursiveArrayIterator , which is part of the PHP SPL, shipped non-optional, with the PHP core.您可以使用\\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.';

Run and play this example in the REPL here: https://3v4l.org/cGtoi在此处的 REPL 中运行并播放此示例: https : //3v4l.org/cGtoi

The code is just meant to verbosely explain what you can expect to see.该代码只是为了详细解释您可以期望看到的内容。 The Iterator walks each level.迭代器遍历每个级别。 How you actually code it is up to you.如何实际编码取决于您。 Keep in mind that filtering or flattening the array (read: transforming it up front) might be another option.请记住,过滤或展平数组(阅读:预先转换它)可能是另一种选择。 You could as well use a generator and emit each level and maybe go with Cooperative Multitasking/ Coroutines as PHP core maintainer nikic explained in his blog post.您也可以使用生成器并发出每个级别,也可以使用协作多任务/协程,正如 PHP 核心维护者nikic在他的博客文章中所解释的那样。

ProTip: Monitor your RAM consumption with different variants in case your nested Array really is large and maybe requested often or should deliver results fast.专业提示:如果您的嵌套数组确实很大并且可能经常被请求或应该快速提供结果,请使用不同的变体监控您的 RAM 消耗。

In case you really need to be fast, consider streaming the result, so you can process the output while you are still working on processing the input array.如果您确实需要快速,请考虑对结果进行流式处理,这样您就可以在处理输入数组的同时处理输出。

A last option might be to split the actual array in chunks (like when you are streaming them), therefore processing smaller parts.最后一个选项可能是将实际数组拆分为块(例如流式传输它们时),从而处理较小的部分。

The case is quite complex, as you have to loop, but you can't or don't want to for some reasons:案例非常复杂,因为您have to循环,但由于某些原因您不能或不想:

... that I need to loop through ...我需要循环

and

I can't use nested loops because this array could contain hundreds of nested arrays我不能使用嵌套循环,因为这个数组可能包含数百个嵌套数组

It means you have to either handle your data differently, as you can pack that huge amount of data to be processed later.这意味着您必须以不同的方式处理数据,因为您可以打包大量数据以供稍后处理。

If for some reasons it's not an option, you can consider to:如果由于某些原因它不是一种选择,您可以考虑:

  • split somehow this big array into smaller arrays以某种方式将这个大数组拆分为较小的数组
  • check how does it work with json_encode and parsing string with str_* functions and regex检查它如何使用json_encode以及使用str_*函数和正则表达式解析字符串

Your question contains too many things we can't be sure eg what exactly these subarrays contain, can you ignore some parts of them, can you change the code that creates huge array in first place etc.您的问题包含太多我们无法确定的内容,例如这些子数组究竟包含什么内容,您是否可以忽略其中的某些部分,您是否可以更改首先创建大型数组的代码等。

Assuming on the other hand that you could loop.另一方面,假设你可以循环。 What could bother you?什么会打扰你? The memory usage, how long it will take etc.?内存使用情况,需要多长时间等? You can always use cron to run it daily etc. but the most important is to find the cause why you ended up with huge array in the first place.你总是可以使用 cron 每天运行它等等,但最重要的是找到你最终得到巨大数组的原因。

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

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