在PHP中,您可以。。。

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

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

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


当前回答

也可以使用生成器生成序列。不同之处在于序列中的每个值都是延迟加载的。spread运算符和for为结果工作。星号符号使函数成为生成器。

const range = function*(from,to) {   
    for(let i = from; i <= to; i++) yield I;   
};   

[...range(3,5)]// => [3, 4, 5]

其他回答

我发现了一个与PHP中的函数相当的JS范围函数,在这里工作得非常棒。向前和向后工作,可以处理整数、浮点数和字母!

function range(low, high, step) {
  //  discuss at: http://phpjs.org/functions/range/
  // original by: Waldo Malqui Silva
  //   example 1: range ( 0, 12 );
  //   returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
  //   example 2: range( 0, 100, 10 );
  //   returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
  //   example 3: range( 'a', 'i' );
  //   returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
  //   example 4: range( 'c', 'a' );
  //   returns 4: ['c', 'b', 'a']

  var matrix = [];
  var inival, endval, plus;
  var walker = step || 1;
  var chars = false;

  if (!isNaN(low) && !isNaN(high)) {
    inival = low;
    endval = high;
  } else if (isNaN(low) && isNaN(high)) {
    chars = true;
    inival = low.charCodeAt(0);
    endval = high.charCodeAt(0);
  } else {
    inival = (isNaN(low) ? 0 : low);
    endval = (isNaN(high) ? 0 : high);
  }

  plus = ((inival > endval) ? false : true);
  if (plus) {
    while (inival <= endval) {
      matrix.push(((chars) ? String.fromCharCode(inival) : inival));
      inival += walker;
    }
  } else {
    while (inival >= endval) {
      matrix.push(((chars) ? String.fromCharCode(inival) : inival));
      inival -= walker;
    }
  }

  return matrix;
}

这是缩小版:

function range(h,c,b){var i=[];var d,f,e;var a=b||1;var g=false;if(!isNaN(h)&&!isNaN(c)){d=h;f=c}else{if(isNaN(h)&&isNaN(c)){g=true;d=h.charCodeAt(0);f=c.charCodeAt(0)}else{d=(isNaN(h)?0:h);f=(isNaN(c)?0:c)}}e=((d>f)?false:true);if(e){while(d<=f){i.push(((g)?String.fromCharCode(d):d));d+=a}}else{while(d>=f){i.push(((g)?String.fromCharCode(d):d));d-=a}}return i};

范围(开始、结束、步骤):使用ES6迭代器

你只要求上限和下限。在这里,我们也创建了一个带步骤的。

您可以轻松创建range()生成器函数,该函数可以用作迭代器。这意味着您不必预先生成整个阵列。

function * range ( start, end, step = 1 ) {
  let state = start;
  while ( state < end ) {
    yield state;
    state += step;
  }
  return;
};

现在,您可能需要创建一个从迭代器预生成数组并返回列表的东西。这对于接受数组的函数很有用。为此,我们可以使用Array.from()

const generate_array = (start,end,step) =>
  Array.from( range(start,end,step) );

现在您可以轻松生成静态数组,

const array1 = generate_array(1,10,2);
const array1 = generate_array(1,7);

但是,当需要迭代器(或允许您使用迭代器)时,您也可以轻松创建迭代器。

for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
  console.log(i)
}

特别注意事项

如果你使用Ramda,他们和Lodash一样有自己的R.range

这是我用于数字范围的方法:

const rangeFrom0 = end => [...Array(end)].map((_, index) => index);

or

const rangeExcEnd = (start, step, end) => [...Array(end - start + 1)]
   .map((_, index) => index + start)
   .filter(x => x % step === start % step);
var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);

根据我的理解:

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);

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