ES6/7 相当于下划线的范围函数

ES6/7 equivalent to underscore’s range function

是否有任何 ECMAScript 6/7 等同于下划线的 range 函数?

下划线:

_.range(startPage, endPage + 1);

在 ES2015 中:

Array.from(Array(n), (_, i) => x + i)

不确定 ES2015 版本如何工作。我想知道 javascript 的 ecmascript 范围如何工作

想法是创建一个长度为 end - start + 1 的数组,然后使用 Array#from.

用相关数字填充它

The Array.from() method creates a new Array instance from an array-like or iterable object.

在这种情况下,Array#from 需要一个长度为 属性 的对象。使用 Array(n) 创建这样一个对象(数组)。也可以直接使用{ length: n }。在这种情况下 n = Math.abs(end - start) + 1.

Array#from 接受一个 mapFn 回调,一个可以转换迭代值的函数。该函数接收 2 个参数 - 值(在这种情况下我们可以忽略)和索引(基于 0)。将 start 添加到当前索引将创建范围内的数字。

const range = (start, end) => Array.from(
  Array(Math.abs(end - start) + 1), 
  (_, i) => start + i
);

console.log(range(5, 10));
console.log(range(-10, -5));
console.log(range(-5, 10));

此版本也将处理反向范围(从大到小):

const range = (start, end) => {
  const inc = (end - start) / Math.abs(end - start);
  
  return Array.from(
    Array(Math.abs(end - start) + 1), 
    (_, i) => start + i * inc
  );
};

console.log(range(5, 10));
console.log(range(-5, -10));
console.log(range(10, -5));

请注意,以下实现不允许延迟生成的列表:

Array.from(Array(n), (_, i) => x + i)

假设您需要一个 100 万个数字的列表:

range(1, 1000000);

你打算把它们都吃掉吗?也许不是,但是所有的数字都已经生成了,它们可能在你的记忆中留下了不平凡的足迹。

要是能按需一一搞定就好了

事实证明,我们可以使用生成器做到这一点:

function* range(start, end, step = 1) {
  for (let value = start; value < end; value += step) {
    yield value;
  }
}

for (let x of range(1, Infinity)) {
  if (x > 10) {
    break;
  }
  console.log(x);
}

您注意到 range(1, Infinity) 位了吗?

在所有数字都是预先生成的经典实现中,此代码甚至不会 运行 因为您会陷入无限的数字生成循环。