在 JavaScript 中使用递归获取范围数字

spa*_*Dog 4 javascript recursion range

我正在尝试使用递归来获取数字范围。有人可以向我解释为什么它不起作用吗?

function range(x,y){
    var results = [];
    if(x === y){
        return results;
    }



return  results.push(range(x + 1,y));
}

range(1,5);
Run Code Online (Sandbox Code Playgroud)

小智 6

递归的美妙之处在于你不需要局部变量(var results)。您只需将状态作为参数传递给每个递归迭代:

const concat = (xs, y) => xs.concat(y);

const range = (x, y) => {
  const rec = (x, y, acc) => x < y ? rec(x + 1, y, concat(acc, x)) : acc;
  return rec(x, y, []);
}
Run Code Online (Sandbox Code Playgroud)

ES5 版本,以防您不熟悉箭头语法:

function concat(xs, y) {
  return xs.concat(y);
}

function range(x, y) {
  function rec(x, y, acc) {
    return x < y ? rec(x + 1, y, concat(acc, x)) : acc;
  }

  return rec(x, y, []);
}
Run Code Online (Sandbox Code Playgroud)

但这不是最优雅的解决方案!

通过递归,我们可以通过每次递归调用简单地构建堆栈。每个堆栈帧都包含计算的部分结果。然后我们只需要展开堆栈并将每个部分结果附加到一个数组:

const range = (x, y) => x < y ? [x].concat(range(x + 1, y)) : [];
Run Code Online (Sandbox Code Playgroud)

或者更实用:

const concat = (xs, y) => xs.concat(y);
const range = (x, y) => x < y ? concat([x], range(x + 1, y)) : [];
Run Code Online (Sandbox Code Playgroud)

请注意,这concat([x], range(x + 1, y))是递归情况和[]基本情况。


小智 5

尝试这个:

function rangeOfNumbers(startNum, endNum) {
 if (startNum - endNum === 0) {
  return [startNum];
 } else {
  const numbers = rangeOfNumbers(startNum + 1, endNum);    
  numbers.unshift(startNum);
  return numbers;
 }
};
Run Code Online (Sandbox Code Playgroud)