JavaScript是否具有类似“ range()”的方法来在提供的范围内生成范围?

在PHP中,您可以...

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

也就是说,有一个函数可让您通过传递上下限来获得一定范围的数字或字符。

为此,JavaScript是否内置任何内置功能?如果没有,我将如何实施?

TomTony2020/03/10 14:23:21

This one works also in reverse.

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 ]
JinJin2020/03/10 14:23:21

d3 also has a built-in range function. See https://github.com/mbostock/d3/wiki/Arrays#d3_range:

d3.range([start, ]stop[, step])

Generates an array containing an arithmetic progression, similar to the Python built-in range. This method is often used to iterate over a sequence of numeric or integer values, such as the indexes into an array. Unlike the Python version, the arguments are not required to be integers, though the results are more predictable if they are due to floating point precision. If step is omitted, it defaults to 1.

Example:

d3.range(10)
// returns [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
伽罗猪猪理查德2020/03/10 14:23:21

My codegolfing coworker came up with this (ES6), inclusive:

(s,f)=>[...Array(f-s+1)].map((e,i)=>i+s)

non inclusive:

(s,f)=>[...Array(f-s)].map((e,i)=>i+s)
小哥TonyEva2020/03/10 14:23:21

you can use lodash function _.range(10) https://lodash.com/docs#range

老丝阿飞2020/03/10 14:23:21

Though this is not from PHP, but an imitation of range from Python.

function range(start, end) {
    var total = [];

    if (!end) {
        end = start;
        start = 0;
    }

    for (var i = start; i < end; i += 1) {
        total.push(i);
    }

    return total;
}

console.log(range(10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
console.log(range(0, 10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(5, 10)); // [5, 6, 7, 8, 9] 
JinJin宝儿2020/03/10 14:23:21

A rather minimalistic implementation that heavily employs ES6 can be created as follows, drawing particular attention to the Array.from() static method:

const getRange = (start, stop) => Array.from(
  new Array((stop - start) + 1),
  (_, i) => i + start
);
米亚逆天2020/03/10 14:23:21

I would code something like this:

function range(start, end) {
    return Array(end-start).join(0).split(0).map(function(val, id) {return id+start});
}  

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

range(3,9);
// [3,4,5,6,7,8]

It behaves similarly to Python range:

>>> range(-4,2)
[-4, -3, -2, -1, 0, 1]
Near理查德路易2020/03/10 14:23:21

Did some research on some various Range Functions. Checkout the jsperf comparison of the different ways to do these functions. Certainly not a perfect or exhaustive list, but should help :)

The Winner is...

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

Technically its not the fastest on firefox, but crazy speed difference (imho) on chrome makes up for it.

Also interesting observation is how much faster chrome is with these array functions than firefox. Chrome is at least 4 or 5 times faster.

蛋蛋蛋蛋2020/03/10 14:23:21

Another version using ES6 generators ( see great Paolo Moretti answer with ES6 generators ):

const RANGE = (a,b) => Array.from((function*(x,y){
  while (x <= y) yield x++;
})(a,b));

console.log(RANGE(3,7));  // [ 3, 4, 5, 6, 7 ]

Or, if we only need iterable, then:

const RANGE_ITER = (a,b) => (function*(x,y){
  while (x <= y) yield x++;
})(a,b);

for (let n of RANGE_ITER(3,7)){
  console.log(n);
}

// 3
// 4
// 5
// 6
// 7
神乐卡卡西2020/03/10 14:23:21

Using Harmony spread operator and arrow functions:

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

Example:

range(10, 15);
[ 10, 11, 12, 13, 14, 15 ]
米亚小胖2020/03/10 14:23:21
var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);
Pro逆天2020/03/10 14:23:21

这是我的2美分:

function range(start, count) {
  return Array.apply(0, Array(count))
    .map((element, index) => index + start);
}
阿飞路易2020/03/10 14:23:21

它适用于字符和数字,通过可选步骤前进或后退。

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

jsFiddle

如果您想扩展本机类型,则将其分配给Array.range

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

console.log(range("A", "Z", 1));
console.log(range("Z", "A", 1));
console.log(range("A", "Z", 3));


console.log(range(0, 25, 1));

console.log(range(0, 25, 5));
console.log(range(20, 5, 5));

阳光阿飞2020/03/10 14:23:21

我最喜欢的新表格(ES2015

Array(10).fill(1).map((x, y) => x + y)

如果您需要带有step参数的函数

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)
LEY宝儿2020/03/10 14:23:21

对于数字,您可以使用ES6 Array.from()它在当今除IE之外的所有内容中都适用

较短的版本:

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

较长版本:

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

这将创建一个从0到19(含0)的数组。可以将其进一步简化为以下形式之一:

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