Explain to me how this recursion works

Tell us what’s happening:
I’m failing to understand how this ouputs the proper array.
If startNum = 1 and endNum = 5 then startNum won’t be returned because startNum != endNum.
So var number will end up being “rangeOfNumbers(1, 5 -1);”
endNum is now 4.
“number.push(4)” should put 4 at the end of the array and then number is returned to the function where it will push smaller numbers to the end of the array [4, 3, 2, 1].
However the array when running the code ends up being [1, 2, 3, 4, 5].
There is obviously something I can’t quite wrap my head around so if someone could dumb it down as much as possible for me I would be extremely appreciative! Thanks :smiley:

Your code so far

function rangeOfNumbers(startNum, endNum) {
if (startNum === endNum){
  return [startNum];
} else {
  var number = rangeOfNumbers(startNum, endNum - 1);
  return number;

1, 5
1 != 5;
1, 4


Your browser information:

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

Challenge: Use Recursion to Create a Range of Numbers

Link to the challenge:

If the two values are equal, the range is just a single value in an array. Otherwise what you want is to return is the value of the (badly named) variable number (which is actually the range, an array of numbers).

What the function is doing is taking that array and pushing the next value in the range on, in a loop. But the value of that array before pushing the next value on, is a call to the function itself with one of the arguments decremented. Which in turn triggers another call and so on until you hit the case where the two values are identical.

At which point the start value is an array with one value, so you solve the next function call by inputting that value, which lets you solve the next function call by inputting the return value there and so on.

The function recurses until it reaches its base case, building up a stack of function calls, then unwinds back to the top. As it unwinds, each function call can now be resolved to a value.

rangeOfNum(1, 5)
  rangeOfNum(1, 4)
    rangeOfNum(1, 3)
      rangeOfNum(1, 2)
        rangeOfNum(1, 1)
        value of `number` is [1]
      value of `number` is [1, 2]
    value of `number` is  [1, 2, 3]
  value of `number` is [1, 2, 3, 4]
value of `number` is [1, 2, 3, 4, 5],
stack has now gone all the way back up.

This is imo a really confusing example, it’s kinda elegant but imo even coming from languages where there are no loops and recursion is mandatory this is difficult to grok