# Basic JavaScript - Use Recursion to Create a Range of Numbers

Can someone help me figure out why I need to use “unshift” instead of “push”? Isn’t the first value that is pushed to the array 5? And if I use “push,” shouldn’t the value after that be on the right side, resulting in an overall return of [5, 6, 7, 8]? Why is it reversed, and why do I have to change it to “unshift”? I’m quite confused.

``````function rangeOfNumbers(startNum, endNum) {
if (startNum > endNum){
return [];
}else{
const numberArray = rangeOfNumbers(startNum + 1, endNum);
numberArray.unshift(startNum);
return numberArray;
}
};

console.log(rangeOfNumbers(5, 8));
``````

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

Challenge: Basic JavaScript - Use Recursion to Create a Range of Numbers

It is evaluated from the last call to the first, backwards, so if you use `push` you will end up with the numbers in the opposite direction to what you were expecting:

Take:

``````rangeOfNumbers(1, 3);
``````

Inside the function, you are going to set the value of the variable `numberArray`, and then return it. How many times `rangeOfNumbers` gets called is important. It’s been called once so far. Then:

``````// 1 is not greater than 3, so go to `else`
const numberArray = rangeOfNumbers(2, 3);
``````

`rangeOfNumbers` has been called twice, like `rangeOfNumbers1(rangeOfNumbers2)`.

`numberArray` is not a concrete value yet, it’s a function call.

``````// 2 is not greater than 3, so go to `else`
const numberArray = rangeOfNumbers(3, 3);
``````

`rangeOfNumbers` has been called three times, like `rangeOfNumbers1(rangeOfNumbers2(rangeOfNumbers3))`.

`numberArray` is not a concrete value yet, it’s a function call.

``````// 4 IS greater than 3
const numberArray = rangeOfNumbers(4, 3);
``````

Now, when we increment the first argument by one, we get `rangeOfNumbers(4, 3)`. This returns an actual value: we don’t go to the `else`, we do not call `rangeOfNumbers`, we return a value, `[]`. And now that `rangeOfNumbers` is actually returning values, go back up that chain of nested functions, from the innermost call to the outermost.

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

Innermost call: `numberArray` equals `[]`, next line says `unshift` startNum, which is 3.
Move back a level, `numberArray` equals `[3]`, next line says `unshift` startNum, which is 2.
Move back a level, `numberArray` equals `[2, 3]`, next line says `unshift` startNum, which is 1.
Move back a level, we’re back at the start, return `numberArray`, which is now `[1, 2, 3]`.

If it had been `push` instead:

1. Innermost call: `numberArray` equals `[]`, next line says `push` startNum, which is 3.
2. Move back a level, `numberArray` equals `[3]`, next line says `push` startNum, which is 2.
3. Move back a level, `numberArray` equals `[3, 2]`, next line says `push` startNum, which is 1.
4. Move back a level, we’re back at the start, return `numberArray`, which is now `[3, 2, 1]`.

(closest comparison I could think of without thinking about it too much – can probably get a direct analogy using a do/while loop, but this should do):

``````function rangeOfNumbers(start, end) {
let numberArray = [];
for (let i = end; i >= start; i--) {
numberArray.unshift(i);
}
return numberArray;
}
``````
1. `rangeOfNumbers(1, 3)`
2. `numberArray` is `[]`
3. `i` is 3, that is greater than or equal to 1, `numberArray` is `[3]`
4. `i` is 2, that is greater than or equal to 1, `numberArray` is `[2, 3]`
5. `i` is 1, that is greater than or equal to 1, `numberArray` is `[1, 2, 3]`
6. `i` is 0, that is NOT greater than or equal to 1, loop ends.
7. return `[1, 2, 3 ]`

Also, just for comparison another way to do it recursively which doesn’t mutate the array, and is basically a same as a loop (mutating IMO confuses things, though it is I guess more efficient):

``````function rangeOfNumbers(start, end, numArr = []) {
if (start > end) {
return numArr;
} else {
return rangeOfNumbers(start + 1, end, numArr.concat(end))
}
}``````

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.