The empty array in this recursive code is accessible how?

。_饼干妹妹 提交于 2021-01-29 16:32:26

问题


I have looked at this long and hard. I understand recursion, I understand the call stack and the concept of “Last in, first out” but in this example.

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

When we meet the 'base condition' and we return []; , how is the array accessible if it does not have a name? and when is the name countArray attributed to this array?

I just don’t get it!


回答1:


It's a return value, so the value is passed back to the caller. For example, on this line:

const countArray = countup(n - 1)

...if n was 1, then 0 is passed to countup, and [] is returned. This means countArray now has the value []. Note that this is not related to recursion at all; it's the way any function call works.




回答2:


Recursion recurses down until n===1. Then, when countup(0) is called (as countup(1-1) , an empty array is returned. In that instant, on the same line, the empty array is assigned to the variable countArray. from there 1 is pushed, and the array [1] is returned, assigned to the countArray 1 level back up the tree, and you continue recursing back up to your starting number.

This is the line where the array assignment occurs:

const countArray = countup(n - 1);

The function is called, and the return result of the function is assigned to the variable. At first it simply recurses to a deeper level. Then, when n==1, it stops recursing, gets assigned an actual value, and begins climbing back up.
It needs this definitive, base value, [] before it can climb out of its deepest level of recursion.




回答3:


The array returned by return [] is the return value of the function countup.

When you do console.log(countup(5)) really you are doing:

let something = countup(5);
console.log(something);

The array returned from the function countup is being assigned to a variable, which is then written out to the console by being passed to console.log.




回答4:


I'm not sure the best way to express this, but a step-by-step walkthrough of how code executes may help. Indentation here indicates a level of recursion (and thus a fresh "scope" for defining variables):

// n = 5
const countArray = countup(n - 1);
  // n = 4
  const countArray = countup(n - 1);
    // n = 3
    const countArray = countup(n - 1);
      // n = 2
      const countArray = countup(n - 1);
        // n = 1
        const countArray = countup(n - 1);
          // n = 0
          // n meets the condition (n < 1), so we return []
        // we got [], as the reutn value and assigned it to countArray
        // countArray = [] a this point
        countArray.push(n);
        // now countArray = [1]
        // return [1]
      // we got [1], as the reutn value and assigned it to countArray
      // countArray = [1] a this point
      countArray.push(n);
      // now countArray = [1, 2]
      // return [1, 2]
    // we got [1, 2], as the reutn value and assigned it to countArray
    // countArray = [1, 2] a this point
    countArray.push(n);
    // now countArray = [1, 2, 3]
    // return [1, 2, 3]
  // we got [1, 2, 3], as the reutn value and assigned it to countArray
  // countArray = [1, 2, 3] a this point
  countArray.push(n);
  // now countArray = [1, 2, 3, 4]
  // return [1, 2, 3, 4]
// we got [1, 2, 3, 4], as the reutn value and assigned it to countArray
// countArray = [1, 2, 3, 4] a this point
countArray.push(n);
// now countArray = [1, 2, 3, 4, 5]
// return [1, 2, 3, 4, 5]

// This value is then console logged



回答5:


let's see two ways to declare an empty array

const a = [];
const b = new Array();
console.log(a) // []
console.log(b) // []

So you get the same output, now with your question, [] is a way to declare an array, and javascript knows it.

Then if you have the function:

function countup(n) {
if (n < 1) {
  // return [];
  return new Array();
} else {
    const countArray = countup(n - 1);
    countArray.push(n);
    return countArray;
  }
}
console.log(countup(5)); // [ 1, 2, 3, 4, 5 ]

Maybe this way you can figure it out what is happening, you are creating and returning a new empty array, to end the clarification, let's change the function call:

// console.log(countup(5)); // [ 1, 2, 3, 4, 5 ]
const newArrayUpToFive = countup(5);
console.log(newArrayUpToFive); // [ 1, 2, 3, 4, 5 ]

// Now the empty array

const newArrayEmpty = countup(0) // the return value is new Array()
// const newArrayEmpty = new Array(); // It is like this sentence

console.log(newArrayEmpty) // []

Step by step:

console.log(countup(2));

// The function does (as n = 2)
const countArray = countup(1) // 2 - 1, Let's say this is the 'A' call
// The function has to wait for the countup return statement

// Now countup is called again with n = 1, and we have
const countArray = countup(0) // 1 - 1, 'B' call
// Again, the function has to wait for the countup return statement

// Finally countup is called n = 0 and the if condition
// is true, so:
   return [];

// B call gets the value [], in 'B' call the value of n was 1
const countArray = [];
countArray.push[1]
return countArray; // returns [1]

// A call gets the value [1], in 'A' call the value of n was 2
const countArray = [1];
countArray.push(2);
return countArray; // returns [1, 2]

So at the end, console.log is called with the value [1, 2].




回答6:


Recursion is a functional heritage and so using it with functional style yields a greater comprehension. In functional programming, you can simply replace a function call with it's return value and always get the correct answer. This is not always true for imperative programs which rely on side-effects to compute the result.

I think it helps to see the program and the spawned process like this -

const countup = (n = 0) =>
  n < 1
    ? []
    : [ ...countup(n - 1), n ]
    
console.log(countup(4))
// [ ...countup(3), 4 ]
// [ ...[ ...countup(2), 3 ], 4 ]
// [ ...[ ...[ ...countup(1), 2 ], 3 ], 4 ]
// [ ...[ ...[ ...[ ...[], 1 ], 2 ], 3 ], 4 ]
// [ ...[ ...[ ...[ 1 ], 2 ], 3 ], 4 ]
// [ ...[ ...[ 1, 2 ], 3 ], 4 ]
// [ ...[ 1, 2, 3 ], 4 ]
// [ 1, 2, 3, 4 ]

I'm not saying it's a better program (or worse!) but I do think it's easier to see how the recursive program directly relates to the recursive computational process.



来源:https://stackoverflow.com/questions/62205712/the-empty-array-in-this-recursive-code-is-accessible-how

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!