Flatten an Array / by Zach Mayer

I'm tired today, so I want to look at an easier problem.

Write a function that accepts an array of arbitrary type, which may contain nested arrays. Return the same array with values in the nested arrays promoted to the top-level parent.

So given an input like this...

[ 1, 2, {'a':2.5}, 3, [4, [5, [6, 7], 8, [9, 0]]] ]

Turn it into an array like this...

[ 1, 2, { a: 2.5 }, 3, 4, 5, 6, 7, 8, 9, 0 ]

Someone familiar with the Array.reduce() function might immediately feel like it's a good fit, and they'd be right if each item in the input array was also an array. The problem with reduce for this input is that you can't back-track easily, so your solution will most likely be some form of recursion.

There's still a simple solution however, and I think it's pretty elegant. Using Array.splice() and a cursor we can decrement whenever we need to flatten an array we can step through the input array iteratively and continuously until even deeply nested arrays are bubbled up to the top level.

This solution works because Array.splice() takes an arbitrary number of arguments after the first two, and each of those arguments is an item to be cut into the target array. Before the array spread operator (...) we'd need to use Function.apply() and concatenate our nested array with the first two arguments for splice, then apply that array of arguments to splice for the target array. Something like this...

Array.prototype.splice.apply(arr, [i, 1].concat(arr[i]));

With array spreading we can do the same thing with much better readability, as demonstrated:

It should be noted that this solution modified the original array in-place. It's trivial to modify this to be a function on Array.prototype, which would allow for perhaps a prettier syntax like input.flatten()

I prefer the un-prototyped solution personally, if only because "don't mess with common language prototypes" is seared into my brain from long ago.