【问题标题】:A range of numbers in jsjs中的数字范围
【发布时间】:2021-07-01 11:56:18
【问题描述】:

所以我想创建一个递归函数,将一系列数字推入数组中。 所以我做了以下事情:

function rangeOfNumbers(startNum, endNum) {
  let arr = [];
  
  if (startNum != endNum) {
    rangeOfNumbers(startNum++, endNum);
    arr.push(startNum);
  } else {
    arr.push(endNum);
  }
  
  return arr;
};

console.log(rangeOfNumbers(1, 5));

所以我认为应该工作的方式是,在每次迭代中 startNum 应该是 +1 并且应该被推入数组内部,并且当 startNum 在这种情况下达到 endNum 的值 5 时,我们应该推 endNum 并结束递归,为什么是我的逻辑有问题,因为现在发生的事情是我的函数超过了最大调用堆栈。

我尝试的另一件事是:

function rangeOfNumbers(startNum, endNum) {
  let arr = [];
  
  if (startNum == endNum) {
    return arr.push(endNum);
  } else {
    rangeOfNumbers(startNum++, endNum);
    arr.push(startNum);
  }
  
  return arr;
};

仍然超出调用堆栈,为什么会这样? :(

【问题讨论】:

  • 请注意 startNum++ 返回原始数字,如果您想要增加的数字,您需要使用 ++startNum 或只需执行 startNum + 1
  • startNum++ 如何返回原始数字?它不应该增加它吗?
  • 它确实增加了值,但返回了原始值。你可以了解更多over at MDN。描述告诉你的区别比我做得更好。
  • 哦,天哪,我现在怎么知道这个 :D 这是一个非常有价值的答案,非常感谢!!!
  • 为什么要使用递归呢?为什么不是一个简单的循环?这像是编写递归函数的练习吗?

标签: javascript arrays recursion


【解决方案1】:

您只是从第一次迭代中返回数组。

您需要将数组作为递归函数的参数之一,以便所有推送都进入同一个数组

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

编辑: 您可能还想在推送之后调用递归,以便它们都按顺序排列。

并且我还将比较运算符更改为

【讨论】:

    【解决方案2】:

    您必须将数组放入参数中:

    let arr = [];
    
    function rangeOfNumbers(startNum, endNum, arr) {
      if (startNum !== endNum) {
        arr.push(startNum);
        rangeOfNumbers(startNum + 1, endNum, arr);
      } else {
        arr.push(endNum);
      }
    
      return arr;
    }
    
    console.log(rangeOfNumbers(1, 5, arr));
    【解决方案3】:

    您在每次调用时都重新定义了 arr 变量,并且从不使用从更深入的调用返回的数组。您可以像 Basto 在他们的回答中那样传递单个数组引用,也可以运行递归并仅在终端调用中定义数组,然后将 unshift() 每个 startNum 定义到返回的数组中。

    function rangeOfNumbers(startNum, endNum) {
      const arr = startNum < endNum ? rangeOfNumbers(startNum + 1, endNum) : [];
      
      arr.unshift(startNum);
    
      return arr
    };
    
    console.log(rangeOfNumbers(1, 5));

    unshift() 虽然很慢。您可以通过减少“endNum”而不是增加“startNum”来更改使用push() 的逻辑,并在每次调用时推送“endNum”。

    function rangeOfNumbers(startNum, endNum) {
      const arr = startNum < endNum ? rangeOfNumbers(startNum, endNum - 1) : [];
    
      arr.push(endNum);
    
      return arr
    }
    
    console.log(rangeOfNumbers(1, 5))

    或使用spread syntax (...)

    function rangeOfNumbers(startNum, endNum) {
      return startNum <= endNum
        ? [startNum, ...rangeOfNumbers(startNum + 1, endNum)]
        : [];
    }
    
    console.log(rangeOfNumbers(1, 5));

    【讨论】:

    • 或者当然,作为一个单行:const rng = (s, e) =&gt; s &lt;= e ? [s, ... rng (s + 1, e)] : []
    猜你喜欢
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多