【问题标题】:Javascript recursions. Why the following code works with .unshift() instead of .push()?Javascript 递归。为什么以下代码适用于 .unshift() 而不是 .push()?
【发布时间】:2021-01-01 09:40:29
【问题描述】:

我的大脑认为我应该使用 .push() 而不是 .unshift() 但 freeCodeCamp 和我的控制台告诉我这是正确的做法。我只是不明白为什么我的数字使用 .unshift() 从 10 变为 20,使用 .push() 时从 20 变为 10;

我阅读代码的方式: 如果startNum 大于endNum,则返回一个空数组。否则,创建一个名为 arr 的变量,并将每次代码运行时当前的 startNum 增加 1 并将其返回到数组中。

我做错了什么?

function rangeOfNumbers(startNum, endNum) {
  if (startNum > endNum) {
    return [];
  } else {
    const arr = rangeOfNumbers(startNum + 1, endNum);
    arr.unshift(startNum);
    return arr;
  }
}

console.log(rangeOfNumbers(10, 20));

控制台:(11) [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

【问题讨论】:

  • 以递归方式,最后一个加入栈的调用首先被调用。因此,如果您尝试使用 push 而不是 unshift,您将首先添加最后一个值。

标签: javascript arrays recursion console.log


【解决方案1】:

一种思考方式是想象递归调用已经正常工作。所以rangeOfNumbers(11, 20) 会产生[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]。所以const arr = rangeOfNumbers(startNum + 1, endNum) 意味着arr[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]。现在您有了startNumarr,需要将它们组合起来。 push 将在末尾添加 startNumunshift 正确地将其添加到开头。

但是当我们在这里时,我想建议一种更优雅的方式来表达相同的算法:

const rangeOfNumbers = (start, end) => 
  start > end 
    ? []
    : [start, ... rangeOfNumbers (start + 1, end)]

我们有一个条件表达式,而不是if-else 语句。而且我们不会在这个过程中改变像arr 这样的变量。我认为它也更清晰地表达了算法。当然,口味可能会有所不同,而且,如果您只是在学习 JS,这可能涉及您尚未见过的语法。但是,如果您确实了解它,您可能会同意我对它的优雅的看法。

【讨论】:

    【解决方案2】:

    unshift 将一个元素插入到数组的开头。

    由于您是从 startNum 迭代到 endNum,请考虑倒数第二个递归调用:

    const arr = rangeOfNumbers(startNum + 1, endNum);
    arr.unshift(startNum);
    return arr;
    

    其中startNum 是19,endNum 是20。递归调用返回一个包含一个元素的数组:[20]。然后你需要在合适的位置插入19元素。

    为此,您需要在开头插入 19,以获得:

    [19, 20]
    

    所以,在unshift开头插入19。

    如果您使用 push 代替原来的 [20],您会得到:

    [20, 19] // 19 added to end
    

    然后

    [20, 19, 18] // 18 added to end
    

    等等,顺序不对。

    如果您在递归调用之前插入元素,则可以使用push

    function rangeOfNumbers(startNum, endNum, arr = []) {
      arr.push(startNum);
      if (startNum < endNum) {
        rangeOfNumbers(startNum + 1, endNum, arr);
      }
      return arr;
    }
    
    console.log(rangeOfNumbers(10, 20));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 2013-08-25
      • 2020-02-16
      相关资源
      最近更新 更多