DEV Community

Cover image for Never use array_merge in a loop
Jose M Valera Reales
Jose M Valera Reales

Posted on Edited on Originally published at chemaclass.es

Never use array_merge in a loop

The spread operator to the rescue.

Flattening a one-level array

I have seen people using the array_merge function in a loop like:

$lists = [
  [1, 2],
  [3, 4],
  [5, 6],
];
$merged = [];
foreach($lists as $list) {
    $merged = array_merge($merged, $list);
}
// $merged === [1, 2, 3, 4, 5, 6];
Enter fullscreen mode Exit fullscreen mode

This is a very bad practice because it’s a (memory) performance killer!
Instead, you should use the spread operator (in PHP since 5.6!):

$lists = [
  [1, 2],
  [3, 4],
  [5, 6],
];
$merged = array_merge(...$lists);
// === [1, 2, 3, 4, 5, 6];
Enter fullscreen mode Exit fullscreen mode

Unpacking an assoc-array

What if you had an assoc-array instead like this one?

$lists = [
  'key-1' => [1, 2],
  'key-2' => [3, 4],
  'key-3' => [5, 6],
];
Enter fullscreen mode Exit fullscreen mode

In that case, you will need to unpack its values:

$merged = array_merge(...array_values($lists));
// === [1, 2, 3, 4, 5, 6];
Enter fullscreen mode Exit fullscreen mode

In Functional Programming, this is known as flatting a list.
No loops & no more performance problem.

Flatting a multilevel array

What if you wanted to flat a multilevel array like this one?

$lists = [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []];
Enter fullscreen mode Exit fullscreen mode

Or like this one, even with key-values?

$lists = [
    'key-1' => [
        1,
        [2],
        'key-2' => [
            3,
            [
                'key-3' => [4, 5],
            ],
        ],
    ],
    6,
    'key-4' => [7, 8],
];
Enter fullscreen mode Exit fullscreen mode

In these cases, you might want to use the internal standard library:

$merged = iterator_to_array(
    new RecursiveIteratorIterator(
        new RecursiveArrayIterator($lists)
    ),
    $use_keys = false
);
// $merged === [1, 2, 3, 4, 5, 6, 7, 8];
Enter fullscreen mode Exit fullscreen mode

Conclusion

Usually, being aware of how to flat a “2 level” array might be sufficient:

$flattenList = array_merge(...array_values($lists));
Enter fullscreen mode Exit fullscreen mode

Otherwise, the internal standard library will help you deal with it.

Alt Text

Originally published on https://chemaclass.es/blog/array-merge-in-loop/

Top comments (4)

Collapse
 
moopet profile image
Ben Sinclair •

I try to avoid anything like this in PHP because I always have to look up what the difference is between array_merge and the + operator, and what order to use parameters in and which bits are going to be OO today and which bits aren't. It's just horrible.

I didn't even know there was a spread operator in PHP!

Collapse
 
moopet profile image
Ben Sinclair •

Ah, it looks like it's been in PHP since 5.6 as an argument unpacker but only been able to unpack general arrays since 7.4.

Collapse
 
chemaclass profile image
Jose M Valera Reales •

Well, you can use it for versions <7.4 as:

$merged = array_merge([], ...array_values($lists));
Enter fullscreen mode Exit fullscreen mode

Check it out: sandbox.onlinephpfunctions.com/cod...

And from 7.4, array_merge accept no arguments, therefore we can use it without the empty array as first arg:

$merged = array_merge(...array_values($lists));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
suckup_de profile image
Lars Moelleken •

If you use PhpStorm, then you can use the "Php Inspections ​(EA Extended)" plugin, this will check array functions in loops. :)

⇉ github.com/kalessil/phpinspections...