Ahmed Salameh
Ahmed Salameh

Reputation: 269

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?

Upvotes: 3

Views: 359

Answers (2)

kaiser
kaiser

Reputation: 22363

You could use a \RecursiveArrayIterator, which is part of the PHP SPL, shipped non-optional, with the PHP core.

<?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

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.

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.

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.

Upvotes: 2

PatNowak
PatNowak

Reputation: 5812

The case is quite complex, as you have to loop, but you can't or don't want to for some reasons:

... 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

Your question contains too many things we can't be sure e.g. 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.

Upvotes: 1

Related Questions