Need some explanation for this code

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

Here I don’t understand what this is and why it is needed (n-1)?

This is using a concept called recursion to return an array of numbers from the initial number to 1. Recursion is a programming concept where a method calls itself to perform a similar function with a slightly modified set of data.

In this case, the method is built to return an array of numbers that counts down from the starting number down to 1. It’s using the n - 1 as the “loop” by calling itself with one less than the n until it returns an empty array. Then it goes back “up” the loop, adding the n value to the START of the array using the array unset. Sorry, it’s confusing, but hopefully this chart will explain what it’s doing…

  • n = 5
    • calls countdown with a value of 4 (5 - 1)
    • n = 4
      • calls countdown with a value of 3 (4 - 1)
      • n = 3
        • calls countdown with a value of 2 (3 - 1)
        • n = 2
          • calls countdown with a value of 1 (2 - 1)
          • n = 1
            • calls countdown with a value of 0 (1 - 1)
            • n = 0, so return an empty array
          • back to n = 1, add 1 to the empty array so the array is now [1]
        • back to n = 2, add 2 to the START of the array, so the array is now [2, 1]
      • back to n = 3, add 3 to the START of the array, so the array is now [3,2,1]
    • back to n = 4, add 4 to the START of the array, so the array is now [4,3,2,1]
  • back to n = 5, add 5 to the START of the array, so the array is now [5,4,3,2,1]
  • log the array to the console since control has passed back to the original call. The console will now show [5,4,3,2,1]

Sorry if that seems confusing, but that’s what that code does. And it shows the problem with recursion.
While recursion has it’s uses, it can be abused like in this case as it’s doing a lot of extra work just because someone doesn’t like to do a negative count loop. This code can be rewritten and be a lot less confusing (at least to my eyes)

function loopCount(n) {
  let arr = [];    // create an empty array
  // starting with the value n, add it and each number less than (n - 1, n - 2. etc) down to 1
  for (let i = n; i > 0; i--) {
    arr.push(i); // add the value to the array
  }
  return arr;
}

So this code does this

  • create an empty array
  • set i to the value of n, in the example 5
    • 5 is greater than 0 so add i to the array, which now holds [5], subtract 1 from i
    • 4 is greater than 0 so add i to the array, which now holds [5,4], subtract 1 from i
    • 3 is greater than 0 so add i to the array, which now holds [5,4,3], subtract 1 from i
    • 2 is greater than 0 so add i to the array, which now holds [5,4,3,2], subtract 1 from i
    • 1 is greater than 0 so add i to the array, which now holds [5,4,3,2,1], subtract 1 from i
    • 0 is NOT greater than 0 exit the loop
  • return the array [5,4,3,2,1] to be logged to the console.

Here are the two blocks of code in a codepen just to show they return the same values

3 Likes

Now I’m starting to understand a little