Understanding solution/ steamrollArray

Hey guys,
Please help me to understand recursion better and the solution to the stamrollArray challenge. I have already watched different videos, but they all have only a basic explanation. I would be very thankful for your help.

After looking at the solutions of other people, I could come up with this solution, but I still do not understand why in order to call up the function again for recursion, It has to be pushed into a new array together with a spread operator (newArr.push(…steamrollArray(arr[i])))?
Why can’t I simply call up the function by writing (steamrollArray(arr[i])) without pushing it into a new array with a spread operator?

As far as I could understand if I simply call the function without pushing it into a new array, the new array will be empty with every new recursion.
If I am right, I really would like to know what happens behind the scene when I push the function into a new array? And why it must be pushed together with a spread operator?
Thank you in advance.

Your code so far


function steamrollArray(arr) {
let newArr = [];
for (let i=0; i<arr.length; i++){
  if(!Array.isArray(arr[i])) {
    newArr.push(arr[i])
  } else {
    newArr.push(...steamrollArray(arr[i]))
  }
}
return newArr;
}

steamrollArray([1, [2], [3, [[4]]]]);
console.log(steamrollArray([1, [2], [3, [[4]]]]))

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36.

Challenge: Steamroller

Link to the challenge:

Without the spread syntax, the output of the function will be exactly as the original input (so a lot of nested arrays).

In my opinion is easier to reason about this recursion if we think about the function types and its return.

We specifically instruct steamrollArray to return an Array type.
So when we call the recursion:

newArr.push(...steamrollArray(arr[i]))

we are performing three distinct actions:

  1. calling this function recursively and using its return: which is an Array.
  2. since we know that the above will give us back an array we “unfold” its value with the spread operator.
  3. since the above will now give us back plain number, we push it into the result array.

If this still does make little sense perhaps think about the base case:

if(!Array.isArray(arr[i])) {
    newArr.push(arr[i])
  } 

What we are doing here is once we reach a case where we have a plain value instead of an array, we get that, push it into an array, and return it.
So for each base case we get back a value shaped like this: [x] .
But since we don’t want to push the value as it is, but its content, we spread it and push it into our result.


Hope it make a little sense :smiley:

2 Likes

Hey @bkuberlinov!

I have added spoiler tags around your code for those who haven’t worked on this challenge yet.

Thank you very much for this detailed answer! It’s a perfect explanation. I hope I will be able to read and understand the code, as well as you one day.

I wish you success in all your new beginnings in this New Year!

Just good old practice.

Stick with your journey and goals, and one day you’ll soon be ready to teach me a trick or two.

Happy coding :sparkles: