Flatten Nested Arrays Using PHP

While browsing the MooTools 1.2 source code, I found Array's flatten() method. The flatten() method takes nested arrays and "flattens" them all into one array. I asked myself how I could do that using PHP. The following is what I came up with.

The Result

Array
(
[0] => a
[1] => b
[2] => x
[3] => y
[4] => z
[5] => p
)

As you can see, array_flatten() is used recursively to sniff out values from the original array. While I don't believe I've ever found myself with an array as nested as my example, it's good to know that I can extract the values if necessary.

Two years ago I documented my struggles with Imposter Syndrome and the response was immense. I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions. I've even caught myself reading the post...

I was inspired when I first saw Addy Osmani's original ShineTime blog post. The hover sheen effect is simple but awesome. When I started my blog redesign, I really wanted to use a sheen effect with my logo. Using two HTML elements and...

Every once in a while I find a tiny JavaScript library that does something very specific, very well. My latest find, Fokus, is a utility that listens for text selection within the page, and when such an event occurs, shows a beautiful modal dialog in...

CSS has become more and more powerful over the past few years and CSS transforms are a prime example. CSS transforms allow for sophisticated, powerful transformations of HTML elements. One or more transformations can be applied to a given element and transforms can even be animated...

I went through this same issue with python a couple years ago[1]. Strangely, in all my years of using php, I never really needed flatten (well maybe a couple times it would have been handy). Python doesn’t handle recursion very well, so an iterative version is pretty much a necessity for it to be of any use. Here is a php translation of the python version I ended up using:

It’s much slower than your implementation (I assume because of the overhead of array_splice compared to python’s list.pop, since the python version performs comparably yours–it just doesn’t grok 2000 levels of recursion. In fact, when I use a translation of your php version, python dies very soon with “maximum recursion depth exceeded”).

Ps. One small note, on 5.2.6 I get warnings about trying to accessing invalid indexes from the $array[$x] on lines 7 and 13–prefixing them with “@” prevents them from incurring the slowdown of invoking the warning of course (just thought I’d mention it for posterity).

I did a different approach, since the requirement was also different, and the outcome is boasted
about at php-trivandrum, as function array_flatten

Manu

Thanks for the post, this function is very handy.
Although, as we are retrieving a new array with new indexes it might be nice to have the same function that can flatten an associative array.
Here is your function modified to work with associative array:

@Manu: if you replace $return[] = $value; with $return[$key] = $value; you get the preserve the index names of the source array(s). Don’t know if that’s everyone preference, but that was what I was looking for. If one wanted to make this optional, he could add a 3rd optional parameter to this function to indicate wether or not to preserve index names, like so:

about the code on very top. their is an issue on using for loop, if the nested array have a key, it wont show the value. Instead use foreach loop. I have some revised on the code above, I hope it will help.

Here’s one of the methods that is faster than the recursive iterator version above. Note that by design, this function does NOT preserve all data! You can tweak it to preserve the last entries encountered, by default it returns the first. Tested with random Google Maps API JSON data:

function FLATTEN($a,$key=NULL)
{ // (c) Peter Mugane Kionga-Kamau http://www.visionhive.com - Free for unrestricted use while this notice remains intact.
// Flattens an array (takes k-v pairs from sub-arrays and returns them in one 2-d array).
// Note: the last found value for each key will be used. If you want to use the first
// found value, switch the parameters like so: array_merge(FLATTEN($v,$k),$r)
$r=array();
if(is_array($a))foreach($a as $k=>$v)$r=array_merge($r,FLATTEN($v,$k));
else $r[$key]=$a;
return $r;
}

“If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.

Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array. “

Rafael

Good function and best comments! Great!

Jaco

Couldn’t figure out why the original function required a second parameter, so I rewrote the function.

I expanded upon Jaco’s implementation by having it now be able to handle string keys. I also added the option of defining how much flattening is done. The examples provided should make this more clear. It’s not perfect but I’ve found it useful.

Continue this conversation via emailGet only replies to your comment, the best of the rest, as well as a daily recap of all comments on this post. No more than a few emails daily, which you can reply to/unsubscribe from directly from your inbox.