Recursion - array of numbers - clarification

Hi people, once again I’m thinking about details that bug me.
I’m doing this last excersise and I’m thinking “how come the 4 goes into the array at the end?” the push instruction shouldn’t be executed if the difference between endNum and startNum is equal to 0, arrayOfNumbers isn’t inside the if, and if I change the return statement of the if, I get that value inside the array, so obviously the base case manages to put that number inside the array.
Another thing, I’m still struggling to understand why the final array shows the numbers in ascendent order if there’s a push. I didn’t understand the reason in the previous lesson, I need a dumbed down version, thanks again!

function rangeOfNumbers(startNum, endNum) {
  if (endNum - startNum == 0) {
  return [startNum];
} else {
  let arrayOfNumbers = rangeOfNumbers(startNum, endNum -1) ;
  arrayOfNumbers.push(endNum);
  return arrayOfNumbers;
}  
};


console.log(rangeOfNumbers(4, 4));
console.log(rangeOfNumbers(4, 10));
  **Your browser information:**

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

Challenge: Use Recursion to Create a Range of Numbers

Link to the challenge:

it’s also the first element in the array as it’s the only item that is in the array.

and that is all because of this return statement here, it subtracts startNum from endNum and if result is 0, it returns the value of startNum in an array with no other elements.

change the return statement to what? that could be important piece of information that is missing.

The recursive calls are done until it hits a base case. and only then it does push the numbers to the end of the array.
and apparently I don’t know enough about recursions to explain why it is that way in this specific case.

My bad, I need to explain myself better, ignore completely the function call with just 4, 4 as values, I’m talking about the second call that should return [4, 5, 6, 7, 8, 9, 10].
I don’t fully understand how the 4 gets there, and why the numbers go from smallest to biggest if there’s a push.

Recursion is a complicated subject and is very confusing.

Please search the forum for this challenge and you will see many detailed discussions of it.

I don’t fully understand how the 4 gets there

That is the base case. When endNum finally is equal to startNum, then [startNum] is returned.

why the numbers go from smallest to biggest if there’s a push

Because none of the function calls before the base case can finish because their else is dependent on the next function call. They stack up on the call stack and once the base case is reached, they each complete, popped of the call stack in the opposite order that they were added (LIFO).

That is a confusing idea. Add some log statements and watch it. Or read one of the many detailed explanations that already exist.

Thanks Kevin, as always. Just one more quick question if you don’t mind, I understand that the 4 is the last thing that gets returned, but how come it goes inside the array arrayOfNumbers?

It gets returned:

return [startNum];

startNum is 4. That is the first array. That gets returned to the most recent incomplete function call’s else.

Again, these function calls are not completing in the order they are being called, but in the opposite. Again, add some log statements and watch it happen.

Hi @zuffi.alessandro, I wrote a short faq about recursion (the code is different, but I think that it can be useful):

code

function rangeOfNumbers(startNum, endNum) {
   if(startNum === endNum) {  
     return [endNum]; 
   } else {  
     let arr =  rangeOfNumbers(startNum + 1, endNum); 
     arr.push(startNum); 
     return arr;     
   }
}

let result = rangeOfNumbers(1,4);
console.log(result);
// [ 4, 3, 2, 1 ]

1.- What happens when the base case is evaluated as false?

The function calls itself:
Steps: 4,6,8

2.- What happens when the base case is evaluated as true?

Returns an array:
Step: 10

3.- The Array, where does it come from?

From the base case:
Step: 10

4.- Why can I push startNum to arr?

Because after the base case is evaluated as true, arr is an array:
Step: 11

5.- Why I’m Getting [4,3,2,1] ?

Because JavaScript uses a “stack” (LIFO, last in first out):
Steps: 10, 13, 16, 19

6.- How can I get [1,2,3,4]?

Replace push with unshift

function rangeOfNumbers(startNum, endNum) {
   if(startNum === endNum) {  
     return [endNum]; 
   } else {  
     let arr =  rangeOfNumbers(startNum + 1, endNum); 
     arr.unshift(startNum);  // <-  here  
     return arr;     
   }
}

let result = rangeOfNumbers(1,4);
console.log(result); 
// [ 1, 2, 3, 4 ]

7.- Related topics:

  • nested (function) calls
  • call stack

8.- You can use python tutor to see step by step how the function is executed:

https://pythontutor.com/live.html#mode=edit

Notes:

  • A demo of python tutor:
  • If you know spanish, I recorded a video explaining recursion step by step:
  • I also wrote a blog post (it has 27 images)

https://diegoperezm.github.io/blog/recursion.html

Cheers and happy coding :slight_smile:

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