在PHP中,您可以。。。

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

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

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


当前回答

可以如下创建大量使用ES6的相当简约的实现,特别注意Array.from()静态方法:

const getRange = (start, stop) => Array.from(
  new Array((stop - start) + 1),
  (_, i) => i + start
);

其他回答

使用Harmony排列运算符和箭头函数:

var range = (start, end) => [...Array(end - start + 1)].map((_, i) => start + i);

例子:

range(10, 15);
[ 10, 11, 12, 13, 14, 15 ]

如果在Visual Studio代码中遇到以下错误:

类型“IterableIterator”不是数组类型或字符串类型。使用编译器选项“--downloadIteration”允许迭代迭代器。

而不是

[...Array(3).keys()]

你可以信赖

Array.from(Array(3).keys())

有关下层迭代的更多信息

没有本机方法。但您可以使用Array的过滤方法来实现。

var范围=(数组,开始,结束)=>array.filter((元素,索引)=>索引>=开始和索引<=结束)警报(范围(['a','h','e','l',''','o','s'],1,5))//['h','e','l','o']

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

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

没有一个示例进行了测试,每个步骤都有一个生成递减值的选项。

export function range(start = 0, end = 0, step = 1) {
    if (start === end || step === 0) {
        return [];
    }

    const diff = Math.abs(end - start);
    const length = Math.ceil(diff / step);

    return start > end
        ? Array.from({length}, (value, key) => start - key * step)
        : Array.from({length}, (value, key) => start + key * step);

}

测验:

import range from './range'

describe('Range', () => {
    it('default', () => {
        expect(range()).toMatchObject([]);
    })

    it('same values', () => {
        expect(range(1,1)).toMatchObject([]);
    })

    it('step=0', () => {
        expect(range(0,1,0)).toMatchObject([]);
    })

    describe('step=1', () => {
        it('normal', () => {
            expect(range(6,12)).toMatchObject([6, 7, 8, 9, 10, 11]);
        })

        it('reversed', () => {
            expect(range(12,6)).toMatchObject([12, 11, 10, 9, 8, 7]);
        })
    })

    describe('step=5', () => {

        it('start 0 end 60', () => {
            expect(range(0, 60, 5)).toMatchObject([0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]);
        })

        it('reversed start 60 end -1', () => {
            expect(range(55, -1, 5)).toMatchObject([55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0]);
        })
    })
})