Steamroller recursive solution

Hello everybody!
I have been trying to understand how this algorithm works. And by using console.log() I’ve come to the conclusion that the spread operator is the one doing the job. But I don’t understand why or how.

I would have never thought of this solution even when I really like it. So I believe if I understand it well I will be able to think on this possibility in the future.

function steamrollArray(arr) {
  let flat = [].concat(...arr);
  return flat.some(Array.isArray) ? steamrollArray(flat) : flat;
}

steamrollArray([1, [2], [3, [[4]]]]);

This solution had the following code explanation. Which I don’t think it actually explains how it flattens the array, which I think it’s being done by the spread operator , or maybe I am just missing something:

Code Explanation

  • Use spread operator to concatenate each element of arr with an empty array
  • Use Array.some() method to find out if the new array contains an array still
  • If it does, use recursion to call steamrollArray again, passing in the new array to repeat the process on the arrays that were deeply nested
  • If it does not, return the flattened array

I would really appreciate your help!
Thanks before hand :slight_smile:

This might be even more trickier or even more clever (or both :slight_smile:) than it looks on the first glance.
The way it works is using both spread operator and fact that concat() method can accept multiple arguments. Spread operator expands one level of the array and only after one-by-one each of the expanded elements from (nested) array are concatenated, array is flattened… a bit more.

This might be easier to wrap head around with example, going through just one - [].concat(...arr), where in this case arr = [1, [2], [3, [[4]]]]:

[].concat(...[1, [2], [3, [[4]]]])

can be looked at as:

[].concat(1, [2], [3, [[4]]])

now each separate argument gets added to initially empty array. Firstly just 1, then [2], then [3, [[4]]]. I’m splitting each of these steps on separate line to show it clearly, but this happens just with one [].concat(...arr):

// [].concat(1) -> [1]
[1].concat([2], [3, [[4]]])

// [1] + [2] -> [1, 2]
[1, 2].concat([3, [[4]]])

// [1, 2] + [3, [[4]]] -> [1, 2, 3, [[4]]]
[1, 2, 3, [[4]]]

Resulting array, as it still has nested array inside is then again passed to function to perform flattening.

1 Like

I’ve edited your post.
If you post a full passing solution to a challenge and have questions about it, please surround it with [spoiler] and [/spoiler] tags on the line above and below your solution code.

What a lovely explanation, that was crystal clear!
Thank you so much for your time and answer. :relieved:

1 Like

Thanks for the heads up!