在PHP中,您可以。。。

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

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

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


当前回答

您可以使用lodash函数.range(10)https://lodash.com/docs#range

其他回答

对一些不同的范围函数进行了研究。检查执行这些函数的不同方法的jsperf比较。当然不是一个完美或详尽的列表,但应该有帮助:)

获胜者是。。。

function range(lowEnd,highEnd){
    var arr = [],
    c = highEnd - lowEnd + 1;
    while ( c-- ) {
        arr[c] = highEnd--
    }
    return arr;
}
range(0,31);

从技术上讲,它不是firefox上最快的,但铬合金上的疯狂速度差(imho)弥补了这一点。

还有一个有趣的观察是,与firefox相比,chrome使用这些阵列功能的速度要快得多。Chrome速度至少快4或5倍。

我的实施

export function stringRange(a: string, b: string) {
    let arr = [a + ''];

    const startPrefix = a.match(/([\D])+/g);
    const endPrefix = b.match(/([\D])+/g);

    if ((startPrefix || endPrefix) && (Array.isArray(startPrefix) && startPrefix[0]) !== (Array.isArray(endPrefix) && endPrefix[0])) {
        throw new Error('Series number does not match');
    }

    const startNum = a.match(/([\d])+/g);
    const endNum = b.match(/([\d])+/g);

    if (!startNum || !endNum) {
        throw new Error('Range is not valid');
    }

    let start = parseInt(startNum[0], 10);
    let end = parseInt(endNum[0], 10);

    if (start > end) {
        throw new Error('Ending value should be lessesr that starting value');
    }

    while (start !== end) {
        start++;
        arr.push(startPrefix ? startPrefix[0] + (start + '').padStart(startNum[0].length, '0') : start + '');

    }

    return arr;
}

样本结果

// console.log(range('0', '10'));
// console.log(range('10', '10')); 
// console.log(range('10', '20'));
// console.log(range('10', '20000'));
// console.log(range('ABC10', 'ABC23'));
// console.log(range('ABC10', 'ABC2300'));
// console.log(range('ABC10', 'ABC09')); --> Failure case
// console.log(range('10', 'ABC23')); --> Failure case
// console.log(range('ABC10', '23')); --> Failure case

范围(开始、结束、步骤):使用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

您可以创建自己的es6系列版本

常量范围=(最小值,最大值)=>{const arr=数组(最大-最小+1).fill(0).map((_,i)=>i+min);返回arr;}控制台日志(范围(0,5));console.log(范围(2,8))

要紧密复制的类型脚本函数

/**
 * Create a generator from 0 to stop, useful for iteration. Similar to range in Python.
 * See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
 * See: https://docs.python.org/3/library/stdtypes.html#ranges
 * @param {number | BigNumber} stop
 * @returns {Iterable<number>}
 */
export function range(stop: number | BigNumber): Iterable<number>
/**
 * Create a generator from start to stop, useful for iteration. Similar to range in Python.
 * See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
 * See: https://docs.python.org/3/library/stdtypes.html#ranges
 * @param {number | BigNumber} start
 * @param {number | BigNumber} stop
 * @returns {Iterable<number>}
 */
export function range(
  start: number | BigNumber,
  stop: number | BigNumber,
): Iterable<number>

/**
 * Create a generator from start to stop while skipping every step, useful for iteration. Similar to range in Python.
 * See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
 * See: https://docs.python.org/3/library/stdtypes.html#ranges
 * @param {number | BigNumber} start
 * @param {number | BigNumber} stop
 * @param {number | BigNumber} step
 * @returns {Iterable<number>}
 */
export function range(
  start: number | BigNumber,
  stop: number | BigNumber,
  step: number | BigNumber,
): Iterable<number>
export function* range(a: unknown, b?: unknown, c?: unknown): Iterable<number> {
  const getNumber = (val: unknown): number =>
    typeof val === 'number' ? val : (val as BigNumber).toNumber()
  const getStart = () => (b === undefined ? 0 : getNumber(a))
  const getStop = () => (b === undefined ? getNumber(a) : getNumber(b))
  const getStep = () => (c === undefined ? 1 : getNumber(c))

  for (let i = getStart(); i < getStop(); i += getStep()) {
    yield i
  }
}