如何通过递归的指定步骤找到任何给定整数的范围

how to find the range of any given integer by a specified step with recursion

我想使用递归按指定步骤查找给定整数的范围。

  given number --> -20 
  step --> 4
  returns --> [ -20, -16, -12, -8, -4, -2, 0, 2, 4 ]

到目前为止,我已经能够创建一个递归函数来 return 相应的结果:

function range(num,step,res=[]) {
  const s = num < step ? step : -step; 
  if (num === step + s) return res;
  return num === step ? [...res,num] : range(num+s,step,[...res,num]);
}

console.log(range(5,1)); // [ 5, 4, 3, 2, 1 ]
console.log(range(-8,2)); // [ -8, -6, -4, -2, 0, 2 ]
console.log(range(-20,4)); // [ -20, -16, -12, -8, -4, -2, 0, 2, 4 ]

但是,以下调用 returns Whosebug

console.log(range(-7,2)); // Whosebug!
console.log(range(11,5)); // Whosebug!

我知道代码有问题,但我就是想不出来是什么问题。有人可以指出我正确的方向或告诉我我做错了什么。提前万分感谢:)

更新:

多亏了 TazHinkle 的控制流程,我才得以解决如下问题:

function range(num,step,res=[]) {
  const s = num < step ? step : -step;
  if (num > step && num < step) return res;
  if (num < step && num + s > step) return [...res,num];
  return num === step ? [...res,num] : range(num+s,step,[...res,num]);
}

console.log(range(5,1)); // [ 5, 4, 3, 2, 1 ]
console.log(range(-8,2)); // [ -8, -6, -4, -2, 0, 2 ]
console.log(range(-20,4)); // [ -20, -16, -12, -8, -4, 0, 4 ]
console.log(range(11,5)); // [ 11, 6, 1 ]
console.log(range(-7,2)); // [ -7, -3, -5, -1, 1 ]
console.log(range(-9,4)); // [ -9, -5, -1, 3 ]

大小写范围 (-7,2) 在当前版本中无法解析,因为它将在 1 和 3 之间无限步进(因为它步进 2 并试图到达 2,但它永远不会)。 你可以让它在它过去时放弃,像这样:

function range(num,step,res=[]) {
    const s = num < step ? step : -step;
    const forward = num < step ? true : false;
    if (num === step + s) return res;
    if(forward) {
        if(num + s > step) {
            return [...res,num]
        }
        return num === step ? [...res,num] : range(num+s,step,[...res,num]);
    }else {
        if(num + s < step) {
            return [...res,num]
        }
        return num === step ? [...res,num] : range(num+s,step,[...res,num]);
    }
}

假设您的目标是从第一个参数开始,然后逐步下降,直到最后一个数字为 0、1 或 -1(基本上尽可能接近零)。

首先,将flip-floping step to/from neg/pos 转换为 pos 并为 neg 步骤设置标志:

if (num < 0) {
  n = Math.abs(num);
  neg = true;
} else n = num;

删除这个额外的步骤,使奇数参数无法停止:

if (num === step + s) return res;

这一行的唯一区别是 < 而不是 ===。这将使奇数更接近于 0,偶数更接近于零:

let result = n < step ? [n, ...res] : rangeToZero(n -step, step, [n, ...res]);

最后,如果neg == true我们把每个数字都设为负数(感觉像作弊):

if (neg) {
  return result.map(N => -Math.abs(N));
}

function rangeToZero(num, step, res=[]) {
  let n, neg = false; 
  if (num < 0) {
    n = Math.abs(num);
    neg = true;
  } else n = num;

  let result = n < step ? [n, ...res] : rangeToZero(n -step, step, [n, ...res]);
  if (neg) {
    return result.map(N => -Math.abs(N));
  }
  return result;
}

console.log(rangeToZero(5,1)); // [ 5, 4, 3, 2, 1, 0 ]
console.log(rangeToZero(-8,2)); // [ -8, -6, -4, -2, 0 ]
console.log(rangeToZero(-20,4)); // [ -20, -16, -12, -8, -4, 0 ]
console.log(rangeToZero(10, 3)); // [ 10, 7, 4, 1 ]
console.log(rangeToZero(-7,2)); // [ -7, -3, -5, -1 ]
console.log(rangeToZero(11,5)); // [ 11, 6, 1 ]