在PHP中,您可以。。。

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")

也就是说,有一个函数可以通过传递上下限来获得一系列数字或字符。

JavaScript本机是否有内置的功能?如果没有,我将如何实施?


当前回答

使用范围([start,]stop[,step])签名完成ES6实现:

function range(start, stop, step=1){
  if(!stop){stop=start;start=0;}
  return Array.from(new Array(int((stop-start)/step)), (x,i) => start+ i*step)
}

如果要自动负步进,请添加

if(stop<start)step=-Math.abs(step)

或者更简单地说:

range=(b, e, step=1)=>{
  if(!e){e=b;b=0}
  return Array.from(new Array(int((e-b)/step)), (_,i) => b<e? b+i*step : b-i*step)
}

如果你有巨大的射程,看看保罗·莫雷蒂的发电机方法

其他回答

解决方案:

//best performance
var range = function(start, stop, step) {
    var a = [start];
    while (start < stop) {
        start += step || 1;
        a.push(start);
    }
    return a;
};

//or
var range = function(start, end) {
    return Array(++end-start).join(0).split(0).map(function(n, i) {
        return i+start
    });
}

Javascript提供了一个从给定值创建和填充数组的函数,接收容器数组和映射函数作为参数:

让arr=数组来源(SOURCE_Array,MAP_FUNCTION);

由于MAP_FUNCTION提供了迭代的值和索引,因此可以创建一个空数组(SOURCE_array)并使用索引填充它,如下所示(supposing 10是您所需的长度):

let arr=Array.from(数组(10),(n,索引)=>索引);

输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].

根据我的理解:

JS的运行时环境不支持尾部调用优化。编写任何递归函数来生成一个大范围的函数都会给你带来麻烦。如果我们要处理大量数据,那么创建循环数组可能不是最好的做法。写入大循环会导致事件队列变慢。


function range(start, end, step = 1) {
  const _range = _start => f => {
    if (_start < end) {
      f(_start);
      setTimeout(() => _range(_start + step)(f), 0);
    }
  }

  return {
    map: _range(start),
  };
}

range(0, 50000).map(console.log);

此函数不会引发上述问题。

这里是一个范围函数的定义,它的行为与Python的范围类型完全相同,只是这个函数不是懒惰的。把它变成发电机应该很容易。

范围构造函数的参数必须是数字。如果省略step参数,则默认为1。如果省略了start参数,则默认为0。如果步骤为零,则会引发错误。

range = (start, stop, step=1) => {
    if(step === 0) throw new Error("range() arg 3 must not be zero");

    const noStart = stop == null;
    stop = noStart ? start : stop;
    start = noStart ? 0 : start;
    const length = Math.ceil(((stop - start) / step));

    return Array.from({length}, (_, i) => (i * step) + start);
}

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

这里有一个很好的简单方法,可以在ES6中只使用数字(不知道它的速度比较):

Array.prototype.map.call(' '.repeat(1 + upper - lower), (v, i) => i + lower)

对于单个字符的范围,可以稍微修改一下:

Array.prototype.map.call(' '.repeat(1 + upper.codePointAt() - lower.codePointAt()), (v, i) => String.fromCodePoint(i + lower.codePointAt()));