Creating a counter with recursion

Tell us what’s happening:
So I looked at the answer from this question and am completely confused as to how the code works. I would to know why my code does not work properly to recursively create an array that counts down to 1.

I would also like to know what the purpose of the const arr = countdown(n-1); statement is. I understand that is the recursive case of the algorithm but how is that creating an array? The only place that an array is being made in is the base case so I am very confused. If anyone can shed some light on this problem, it would be much appreciated.

Your code so far


//so this is my code
function countdown(n){
const list=[];
if (n>=1){
  list.unshift(n);
  countdown(n-1);
}
else {
  return [];
}
console.log(list);
}

console.log(countdown(5));

And this is the code from the answer

function countdown(n) {
if (n < 1) {
  return [];
} else {
  const arr = countdown(n - 1);
  arr.unshift(n);
  return arr;
}
}

Your browser information:

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

Challenge: Use Recursion to Create a Countdown

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/use-recursion-to-create-a-countdown

You are correct. The original array does not get created until the base case (n < 1 ) .
The main thing to understand about the following line:

const arr = countdown(n - 1);

is that until n is equal to 1, these calls to countdown are paused and added to the “call stack”. Why? Because it is not until n is equal to 1, that anything is actually returned. In other words, until when countdown(5) is called, we don’t yet know what to assign to arr. Once we get a value returned for countdown(0) (when n is equal to 1), the empty array is returned and then the line below can actually start processing for all the calls that were held up on the “call stack”.

arr.unshift(n);

You can see what is happening by adding some console.log statements.

n = 5
before recursive call
n = 4
before recursive call
n = 3
before recursive call
n = 2
before recursive call
n = 1
before recursive call
n = 0
return an empty array
after adding item to front of arr
[ 1 ]
after adding item to front of arr
[ 2, 1 ]
after adding item to front of arr
[ 3, 2, 1 ]
after adding item to front of arr
[ 4, 3, 2, 1 ]
after adding item to front of arr
[ 5, 4, 3, 2, 1 ]

You can really see what is going on by seeing the values changes real-time using this link

1 Like

the main issues in your code is that you are recreating the empty list at each function call, meaning it never grows, and when n>=1 your function returns undefined, not a value.

Wow I get it now, once it reaches a base case, the empty array is made and then it adds all the recursive calls from the call stack to that array and returns it.

Thank you so much for helping me to understand this. Recursion has been the hardest topic to grasp so far.

1 Like

But you should only create the list on the base case. If you aren’t in the base case, you already have a list and should be adding more elements to that list.

One last thing about this:

if the array is being made in the base case and then storing the evaluations from the recursive calls, how does javascript know that the variable arr is being used to reference the empty list we create during the base case?

because of arr = countdown(n-1)

the value of previous finished function call is stored in arr, then manipulated and returned

1 Like

The way that I think of it is that the recursive function is basically creating nested if statements.

Your base case of n<1 is the outermost if statement. Since that is not true for the first value of ‘n’ (in this case n=5), then it moves on to the else statement utilizing the countdown(n-1) function. Now the original function repeats itself with (n-1), creating the 2nd iteration of the function nested inside the first. This keeps on repeating until the value of n reduces to 0, which in that case, it creates the empty array. Then each nested function resolves itself into the empty array from innermost nested function, to outermost.

Therefore the empty array is resolved first, followed by the inner most value of ‘n’ (n=1), so on and so forth until the outermost value of ‘n’, which is also the original value of ‘n’, resolves as the last piece of the puzzle.

Hopefully this makes sense!

1 Like