Does JavaScript have a method like “range()” to ge

2018-12-31 06:25发布

In PHP, you can do...

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

That is, there is a function that lets you get a range of numbers or characters by passing the upper and lower bounds.

Is there anything built-in to JavaScript natively for this? If not, how would I implement it?

30条回答
若你有天会懂
2楼-- · 2018-12-31 07:03

I was surprised to come across this thread and see nothing like my solution (maybe I missed an answer), so here it is. I use a simple range function in ES6 syntax :

// [begin, end[
const range = (b, e) => Array.apply(null, Array(e - b)).map((_, i) => {return i+b;});

But it works only when counting forward (ie. begin < end), so we can modify it slightly when needed like so :

const range = (b, e) => Array.apply(null, Array(Math.abs(e - b))).map((_, i) => {return b < e ? i+b : b-i;});
查看更多
骚的不知所云
3楼-- · 2018-12-31 07:06

Here's my 2 cents:

    function range(start, count) {
      return Array.apply(0, Array(count))
        .map(function (element, index) { 
          return index + start;  
      });
    }
查看更多
人气声优
4楼-- · 2018-12-31 07:07

Numbers

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]

Character iteration

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"

Iteration

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"

As functions

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

As typed functions

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

lodash.js _.range() function

_.range(10);
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
 => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
 => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"

Old non es6 browsers without a library:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]

console.log([...Array(5).keys()]);

Thanks.

(ES6 credit to nils petersohn and other commenters)

查看更多
怪性笑人.
5楼-- · 2018-12-31 07:07

You can use lodash or Undescore.js range:

var range = require('lodash/range')
range(10)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

Alternatively, if you only need a consecutive range of integers you can do something like:

Array.apply(undefined, { length: 10 }).map(Number.call, Number)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

In ES6 range can be implemented with generators:

function* range(start=0, end=null, step=1) {
  if (end == null) {
    end = start;
    start = 0;
  }

  for (let i=start; i < end; i+=step) {
    yield i;
  }
}

This implementation saves memory when iterating large sequences, because it doesn't have to materialize all values into an array:

for (let i of range(1, oneZillion)) {
  console.log(i);
}
查看更多
余生请多指教
6楼-- · 2018-12-31 07:09

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.

查看更多
不流泪的眼
7楼-- · 2018-12-31 07:09

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);
}
查看更多
登录 后发表回答