# Need help to understand Steamroller solution 1

``````  // Loop over array contents
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
// Recursively flatten entries that are arrays
//  and push into the flattenedArray
flattenedArray.push(...steamrollArray(arr[i]));
} else {
// Copy contents that are not arrays
flattenedArray.push(arr[i]);
}
}
return flattenedArray;
};

// test here
steamrollArray([1, , [3, []]]);
``````

Can someone helps me to understand this solution?
I can’t understand why after returning flattenedArray the code continues looping with the item’s array of the original array (arr).

If you are referring to the `return` statement:

``````return flattenedArray;
``````

When the code reaches that statement the function immediately stops executing and it returns `flattenedArray`, so the code definitely does not continue looping. Also, the `return` statement is outside of the `for` loop and is the last line in the function, so it couldn’t continue looping if it wanted to 2 Likes

I will try to explain with examples:
Before the first return statement the value of arr and flattendArray are:

``````arr: ;
flattenedArray: ;
``````

and after the return statement the values are:

``````arr: [1, , [3, []]];
flattenedArray: ;
``````

I don´t understand why arr change its value.

OK, just to be clear, there is only one `return` statement in this code and it is the very last line of the function. This function is using recursion in the `if` block, perhaps that is what you don’t understand?

The array `arr` is not changing its value. The only thing that is changing its value is the array `flattenedArray`. The function is going through each element in `arr`, but it is not changing anything about `arr`.

I think it might help if you explain what you think this function is doing. Putting it into words is the first step in really understanding what is going on here.

Also, it might help if the entire code were pasted in here. You left out some important stuff at the top.

``````function steamrollArray(arr) {
const flattenedArray = [];
// Loop over array contents
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
// Recursively flatten entries that are arrays
//  and push into the flattenedArray
flattenedArray.push(...steamrollArray(arr[i]));
} else {
// Copy contents that are not arrays
flattenedArray.push(arr[i]);
}
}
return flattenedArray;
};
``````

Actually, it might help to start with a simple example. Can you explain how the function works with the following function call?

``````steamrollArray([2,3])
``````
2 Likes

I will share the link to the solution given from these exercise.
Solution
Sorry if I am not explaining myself properly.

I understand this is solution 1. I’m trying to help you understand what it is doing. I suggested you start by explaining how the function handles the following:

``````steamrollArray([2,3])
``````

Just explain it in words, no code needed. In case you are wondering, I am building to something bigger that I think will help you understand how this function works. But you need to completely understand the easier case where recursion is not used.

1 Like

it simply pushs 2 , 3 into flattenedArray because arr[i] is not an array.
In this case Array.isArray(arr[i]) return false and the code take the else path.
There is no recursion.

That’s a pretty good summary. I would add that the function loops through each item in the array passed into the function. I think you implied it, but I just wanted to make it clear.

So my summary would be, when the array `[2, 3]` is passed into the function then it loops through the array one item at a time, and since each of those items are not an array themselves (they are simple numbers) then the `else` block is executed for each number and the number is pushed onto the `flattenedArray` array and then when the loop is done, `flattenedArray` is returned.

In this specific case, if `[2,3]` is passed into the function then the array `[2,3]` will be returned. I want you to remember this, this is very important. I can’t stress it enough. You now know that when you pass `[2, 3]` into the function it returns `[2, 3]`. I’m serious, please remember this. Don’t make me have to remind you OK, now explain what happens, using the same amount of details I used above, when we call the function as follows:

``````steamrollArray([1, [2,3]])
``````

It might help if you break your explanation up into loop iterations. For example, “the first iteration this happens” and “the second iteration this happens”.

1 Like

The function loop through each item.
arr is pushed directly to flattenedArray because it is not an array.
arr is an array so the function is called itself and then the function loop through each item of [2, 3].
Then arr[i] is not an array so it’s pushed into flattenedArray. Once the loop it is finished the return flattenedArray; is executed and from this point I just get lost.

You are getting lost because you forgot what I told you to remember.

Let’s look at the `if` block.

``````if (Array.isArray(arr[i])) {
flattenedArray.push(...steamrollArray(arr[i]));
}
``````

Let’s put in real values for the example we are using:

``````if (Array.isArray([2, 3])) {
flattenedArray.push(...steamrollArray([2, 3]));
}
``````

Are you with me so far? I just replaced the variable `arr[i]` with the actual value, which in this case is the array `[2, 3]`.

That’s all you need. You don’t need to dig any further. You should be able to tell me what is happening here. I’ll repeat: What did I tell you to remember?

1 Like

The result of steamrollArray([2, 3]) is an array[2,3].
Due to the spread operator (…steamrollArray([2, 3])) this is transform to (2,3) so
flattenedArray.push(…steamrollArray([2, 3])); is equal to flattenedArray.push(2, 3);

Perfect. So do you understand how `steamrollArray([1, [2, 3]])` returns the array `[1, 2, 3]`? The first time through the `for` loop is just the number `1`, so that is pushed onto `flattenedArray`. The second time through the loop we hit the array `[2, 3]` and thus we make the recursive call `steamrollArray([2, 3])` to make sure it is flattened first so that we can then push it onto `flattenedArray`.

We already knew what `steamrollArray([2, 3])` returns because we solved it previously. So in a sense, we cheated a little. In a recursive function, it is solved at the time you call it recursively. But the answer is the same. So when we get to the recursive call in the `if` block:

``````flattenedArray.push(...steamrollArray(arr[i]));
``````

The function waits for `steamrollArray(arr[i])` to execute and return an answer and then we can push that answer onto `flattenedArray`.

The key here is that we know `steamrollArray` will always return a flattened array. This may be the hardest part to comprehend. If the current item in the `for` loop isn’t an array then it can simply be pushed onto `flattenedArray`. But if it is an array, then we recursively call `steamrollArray` for that item to make sure it is flattened. In other words, we keep recursively calling `steamrollArray` until we have nothing but non-array items in the array we are passing to it. We are drilling down into each sub array until there is nothing but numbers.

I’ll try to clarify with some code.

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

There are two items in this array, the number `1` and the array `[2, [3, 4]]`. Don’t let the sub array `[3,4]` fool you. The initial array we are passing in only has two items.

First time through the `for` loop is the number `1` and so we merely push it to `flattenedArray` in the `else` block.

Second (and last time through the array) we have the array `[2, [3,4]]` and thus we make a recursive call in the `if` block.

``````flattenedArray.push(...steamrollArray([2, [3,4]]))
``````

Don’t let the fact that we are making a recursive call here confuse you. It is as if we are calling a completely different function. Think of it as if we had a function called `steamrollArray1` that does the exact same thing as `steamrollArray`. So at this point we have to wait for `steamrollArray([2, [3,4]])` to return its value. I’m hoping at this point you have a fairly good understanding what will happen there, since it’s basically the same thing as the example we did above (`steamrollArray([1, [2,3]])`. Only once `steamrollArray([2, [3,4]])` returns its value can we then complete the original line we were left waiting on:

``````// we are waiting here for steamrollArray([2, [3,4]]) to return a value
flattenedArray.push(...steamrollArray([2, [3,4]]))
``````
1 Like

Thank you so much for taking your time to explain me the solution.

1 Like