简体   繁体   中英

Question about recursive JS - from freecodecamp

There is this function:

 function countup(n) { if (n < 1) { return []; } else { const countArray = countup(n - 1); countArray.push(n); return countArray; } } console.log(countup(5));

How is [] being pushed first? From the code, it looks like it is being counted down from n. Can someone explain?

Bonus question: Why write like this when I can write:

 function countup(n){ let answer = [] for (let i = 1; i <= n; i++){ (i<n)? answer.push(i): answer.push(n) } return answer } console.log(countup(5));

which is a shorter function. thank you in advance!

Even though the numbers are in descending order starting from n , they are actually being pushed smallest number first. This is because before the push() operation can happen we keep going down in the recursion stack when we call countup(n - 1) every layer of the recursion. This is why we reach a point where n < 1 ie 0 where an empty array is returned.

Next, we encounter the first array.push() operation and so the first number that is pushed into the array is actually 1 and not n . Next, the recursion layers start winding up and we push numbers 2, 3, and so on till n .

Yes you can achieve the same using a traditional for loop, but I guess they just want to explain how recursion works.

To understand recursions, sometimes you need to follow the execution of the code manually. Now the following line causes the recursive call and subtracts one from the number and then passes it to the recursive call.

const countArray = countup(n - 1);

Now imagine, if you passed 5 to the initial function call like so:

countup(5);

As 5 is not less than 1, the else block will be executed. The first line in the else block is the recursive call. So when your program encounters the recursive call, it stops execution of the current function until that recursive function call is concluded/returned. So the first recursive call will be:

const countArray = countup(4);

consequently, the same process will be repeated until n equals 0. As 0 is smaller than 1, the if condition will evaluate to true . and it will return an empty array .

After the recursive call, it pushes the number to the array returned by recursive call. so the array at that point will contain [0] and then [0, 1] and it will keep adding numbers till the all recursive calls have been computed and then it will execute the rest of the intial function call.

Often times, recursion can be replaced by loops but thats not the case always. As a programmer one should be aware of this important topic.

Since countup() is fully divided by an if statement that depends on n , let's first see what exectutes for different vales of n .

To make it a lot easier to follow, we'll append our current n to countArray 's variable name:

n == 5:
   const countArray5 = countup(4);
   countArray5.push(5);
   return countArray5;
⋮
n == 1: 
   const countArray1 = countup(0);
   countArray1.push(1);
   return countArray1;
n == 0: 
   return [];

Now let's sequentially expand each inner call to countup(n) :

countup(5) {
   const countArray5 = countup(4);
   countArray5.push(5);
   return countArray5;
}
countup(5) {
  const countArray5 = countup(4) {
     const countArray4 = countup(3);
     countArray4.push(4);
     return countArray4;  
   };
  countArray5.push(5);
  return countArray5;
}

Expanding until countup(0) :

countup(5) {
  const countArray5 = countup(4) {
    const countArray4 = countup(3) {
      const countArray3 = countup(2) {
        const countArray2 = countup(1) {
          const countArray1 = countup(0) // countup(0) returns [] so countArray1 = [];
          countArray1.push(1); // Then push '1' to countArray1;
          return countArray1;  // Return [1] at counterArray2 = countup(1) above
        };
        countArray2.push(2); // countArray2 was [1], now push '2' to make it [1,2]
        return countArray2; // Return [1,2] at countArray3 = countup(2) above 
      };
      countArray3.push(3); // Push '3' to countArray3 => [1,2,3]
      return countArray3;  // return [1,2,3] at countArray4 = countup(3)
    };
    countArray4.push(4);  // Push '4' to countArray4 => [1,2,3,4]
    return countArray4;   // Return [1,2,3,4] at countArray5 = countup(4)
  };
  countArray5.push(5); // Push '5' to countArray5 => [1,2,3,4,5]
  return countArray5;  // countup(5) returns [1,2,3,4,5] 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM