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:11

My new favorite form (ES2015)

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

And if you need a function with a step param:

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step))
    .fill(start)
    .map((x, y) => x + y * step)
查看更多
旧人旧事旧时光
3楼-- · 2018-12-31 07:13

An interesting challenge would be to write the shortest function to do this. Recursion to the rescue!

function r(a,b){return a>b?[]:[a].concat(r(++a,b))}

Tends to be slow on large ranges, but luckily quantum computers are just around the corner.

An added bonus is that it's obfuscatory. Because we all know how important it is to hide our code from prying eyes.

To truly and utterly obfuscate the function, do this:

function r(a,b){return (a<b?[a,b].concat(r(++a,--b)):a>b?[]:[a]).sort(function(a,b){return a-b})}
查看更多
流年柔荑漫光年
4楼-- · 2018-12-31 07:14

... more range, using a generator function.

function range(s, e, str){
  // create generator that handles numbers & strings.
  function *gen(s, e, str){
    while(s <= e){
      yield (!str) ? s : str[s]
      s++
    }
  }
  if (typeof s === 'string' && !str)
    str = 'abcdefghijklmnopqrstuvwxyz'
  const from = (!str) ? s : str.indexOf(s)
  const to = (!str) ? e : str.indexOf(e)
  // use the generator and return.
  return [...gen(from, to, str)]
}

// usage ...
console.log(range('l', 'w'))
//=> [ 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' ]

console.log(range(7, 12))
//=> [ 7, 8, 9, 10, 11, 12 ]

// first 'o' to first 't' of passed in string.
console.log(range('o', 't', "ssshhhooooouuut!!!!"))
// => [ 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 't' ]

// only lowercase args allowed here, but ...
console.log(range('m', 'v').map(v=>v.toUpperCase()))
//=> [ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' ]

// => and decreasing range ...
console.log(range('m', 'v').map(v=>v.toUpperCase()).reverse())

// => ... and with a step
console.log(range('m', 'v')
          .map(v=>v.toUpperCase())
          .reverse()
          .reduce((acc, c, i) => (i % 2) ? acc.concat(c) : acc, []))

// ... etc, etc.

Hope this is useful.

查看更多
谁念西风独自凉
5楼-- · 2018-12-31 07:15

OK, in JavaScript we don't have a range() function like PHP, so we need to create the function which is quite easy thing, I write couple of one-line functions for you and separate them for Numbers and Alphabets as below:

for Numbers:

function numberRange (start, end) {
  return new Array(end - start).fill().map((d, i) => i + start);
}

and call it like:

numberRange(5, 10); //[5, 6, 7, 8, 9]

for Alphabets:

function alphabetRange (start, end) {
  return new Array(end.charCodeAt(0) - start.charCodeAt(0)).fill().map((d, i) => String.fromCharCode(i + start.charCodeAt(0)));
}

and call it like:

alphabetRange('c', 'h'); //["c", "d", "e", "f", "g"]
查看更多
浪荡孟婆
6楼-- · 2018-12-31 07:15

Handy function to do the trick, run the code snippet below

function range(start, end, step, offset) {
  
  var len = (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1;
  var direction = start < end ? 1 : -1;
  var startingPoint = start - (direction * (offset || 0));
  var stepSize = direction * (step || 1);
  
  return Array(len).fill(0).map(function(_, index) {
    return startingPoint + (stepSize * index);
  });
  
}

console.log('range(1, 5)=> ' + range(1, 5));
console.log('range(5, 1)=> ' + range(5, 1));
console.log('range(5, 5)=> ' + range(5, 5));
console.log('range(-5, 5)=> ' + range(-5, 5));
console.log('range(-10, 5, 5)=> ' + range(-10, 5, 5));
console.log('range(1, 5, 1, 2)=> ' + range(1, 5, 1, 2));

here is how to use it

range (Start, End, Step=1, Offset=0);

  • inclusive - forward range(5,10) // [5, 6, 7, 8, 9, 10]
  • inclusive - backward range(10,5) // [10, 9, 8, 7, 6, 5]
  • step - backward range(10,2,2) // [10, 8, 6, 4, 2]
  • exclusive - forward range(5,10,0,-1) // [6, 7, 8, 9] not 5,10 themselves
  • offset - expand range(5,10,0,1) // [4, 5, 6, 7, 8, 9, 10, 11]
  • offset - shrink range(5,10,0,-2) // [7, 8]
  • step - expand range(10,0,2,2) // [12, 10, 8, 6, 4, 2, 0, -2]

hope you find it useful.


And here is how it works.

Basically I'm first calculating the length of the resulting array and create a zero filled array to that length, then fill it with the needed values

  • (step || 1) => And others like this means use the value of step and if it was not provided use 1 instead
  • We start by calculating the length of the result array using (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1) to put it simpler (difference* offset in both direction/step)
  • After getting the length, then we create an empty array with initialized values using new Array(length).fill(0); check here
  • Now we have an array [0,0,0,..] to the length we want. We map over it and return a new array with the values we need by using Array.map(function() {})
  • var direction = start < end ? 1 : 0; Obviously if start is not smaller than the end we need to move backward. I mean going from 0 to 5 or vice versa
  • On every iteration, startingPoint + stepSize * index will gives us the value we need
查看更多
萌妹纸的霸气范
7楼-- · 2018-12-31 07:15

You can also do the following:

const range = Array.from(Array(size)).map((el, idx) => idx+1).slice(begin, end);
查看更多
登录 后发表回答