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];
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];
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],
];
In that case, you will need to unpack its values:
$merged = array_merge(...array_values($lists));
// === [1, 2, 3, 4, 5, 6];
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, []];
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],
];
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];
Conclusion
Usually, being aware of how to flat a “2 level” array might be sufficient:
$flattenList = array_merge(...array_values($lists));
Otherwise, the internal standard library will help you deal with it.
Originally published on https://chemaclass.es/blog/array-merge-in-loop/
Top comments (4)
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!
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.
Well, you can use it for versions <7.4 as:
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:
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...