在PHP中,您可以。。。

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

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

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


当前回答

我最喜欢的是生成器generateRange,它带有另一个运行生成器的函数getRange。与许多其他解决方案相比,这样做的一个优点是不需要的阵列不会多次创建。

function* generateRange(start, end, step = 1) {
    let current = start;
    while (start < end ? current <= end : current >= end) {
        yield current;
        current = start < end ? current + step : current - step;
    }
}

function getRange(start, end, step = 1) {
    return [...generateRange(start, end, step)];
}

console.log(getRange(0, 5)) // [ 0, 1, 2, 3, 4, 5 ]
console.log(getRange(10, 0, 2)) // [ 10, 8, 6, 4, 2, 0 ]

其他回答

可以使用带有数组、for循环和Math.random()变量的函数来解决这个问题。for循环将数字推入数组,数组将包含您范围内的所有数字。然后Math.random()根据数组的长度随机选择一个。

function randNumInRange(min, max) {
  var range = []
  for(var count = min; count <= max; count++) {
    range.push(count);
  }
  var randNum = Math.floor(Math.random() * range.length);
  alert(range[randNum]);
}

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

/**
 * 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
  }
}

这个也反过来。

const range = ( a , b ) => Array.from( new Array( b > a ? b - a : a - b ), ( x, i ) => b > a ? i + a : a - i );

range( -3, 2 ); // [ -3, -2, -1, 0, 1 ]
range( 1, -4 ); // [ 1, 0, -1, -2, -3 ]

对于数字,您可以使用ES6 Array.from(),它现在可以在除IE以外的任何情况下工作:

较短版本:

Array.from({length: 20}, (x, i) => i);

更长版本:

Array.from(new Array(20), (x, i) => i);​​​​​​

这创建了从0到19(包括0到19)的数组。这可以进一步简化为以下形式之一:

Array.from(Array(20).keys());
// or
[...Array(20).keys()];

也可以指定下限和上限,例如:

Array.from(new Array(20), (x, i) => i + *lowerBound*);

一篇文章对此进行了更详细的描述:http://www.2ality.com/2014/05/es6-array-methods.html

我的实施

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