JavaScript function similar to Python () range

Is there a function in JavaScript similar to Python range() ?

I think there should be a better way than writing the following lines every time:

 array = new Array(); for (i = 0; i < specified_len; i++) { array[i] = i; } 
+74
javascript python
Nov 25 '11 at 18:33
source share
17 answers

No , no, but you can do it .

JavaScript implementation in Python range()

Trying to emulate how this works in Python , I would create a function like this:

 function range(start, stop, step) { if (typeof stop == 'undefined') { // one param defined stop = start; start = 0; } if (typeof step == 'undefined') { step = 1; } if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) { return []; } var result = []; for (var i = start; step > 0 ? i < stop : i > stop; i += step) { result.push(i); } return result; }; 

See this jsfiddle for proof.

Comparing range() in JavaScript and Python

It works as follows:

  • range(4) returns [0, 1, 2, 3] ,
  • range(3,6) returns [3, 4, 5] ,
  • range(0,10,2) returns [0, 2, 4, 6, 8] ,
  • range(10,0,-1) returns [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] ,
  • range(8,2,-2) returns [8, 6, 4] ,
  • range(8,2) returns [] ,
  • range(8,2,2) returns [] ,
  • range(1,5,-1) returns [] ,
  • range(1,5,-2) returns [] ,

and its Python python works the exact same way (at least in the indicated cases):

 >>> range(4) [0, 1, 2, 3] >>> range(3,6) [3, 4, 5] >>> range(0,10,2) [0, 2, 4, 6, 8] >>> range(10,0,-1) [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] >>> range(8,2,-2) [8, 6, 4] >>> range(8,2) [] >>> range(8,2,2) [] >>> range(1,5,-1) [] >>> range(1,5,-2) [] 

So, if you need a function to work similarly to Python range() , you can use the above solution.

+78
Nov 25 '11 at 18:38
source share

For a very simple range in ES6:

 let range = n => Array.from(Array(n).keys()) 
+91
Jun 23 '16 at 0:59
source share

2018: this answer continues to receive upvotes, so here's the update. The code below is deprecated, but, fortunately, the standardized ES6 generators and the yield keyword, and they are universally supported on different platforms. An example of using lazy range() with yield can be found here .




In addition to the above, Javascript 1.7+ provides support for iterators and generators that can be used to create the lazy, memory-efficient version of range , simlar for xrange in Python2:

 function range(low, high) { return { __iterator__: function() { return { next: function() { if (low > high) throw StopIteration; return low++; } } } } } for (var i in range(3, 5)) console.log(i); // 3,4,5 
+26
Nov 25 '11 at 23:10
source share

The Python range port function is provided by underscore.js and lodash . (along with many other useful tools). Examples copied from underscores:

 _.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] _.range(0); => [] 
+17
Aug 30 '14 at 16:09
source share

Combining both answers from @Tadeck and @georg , I came up with the following:

 function* range(start, stop, step = 1) { if (typeof stop === 'undefined') { // one param defined stop = start; start = 0; } for (let i = start; step > 0 ? i < stop : i > stop; i += step) { yield i; } } 

To use it in a for loop, you need an ES6 / JS1.7 loop:

 for (let i of range(0, 10, 2)) { console.log(i); } // Outputs => 0 2 4 6 8 
+15
Oct 24 '14 at 19:23
source share

Can be achieved by attaching an iterator to the Number prototype.

  Number.prototype[Symbol.iterator] = function* () { for (var i = 0; i <= this; i++) { yield i } } [...5] // will result in [0,1,2,3,4,5] 

Adapted from Kyle Simpson's course Rethinking Asynchronous JavaScript

+12
Aug 14 '17 at 0:37
source share

Here you go.

This will record (or overwrite) the value of each index with the index number.

 Array.prototype.writeIndices = function( n ) { for( var i = 0; i < (n || this.length); ++i ) this[i] = i; return this; }; 

If you do not specify a number, it will use the current length of the array.

Use it as follows:

 var array = [].writeIndices(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
+7
Nov 25 '11 at 18:48
source share

Here is a small extension for one of the answers in case you need to specify the start and end positions of the range:

 let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start); 
+5
Dec 20 '16 at 17:09
source share

The following is a natural adaptation of Python range () for JavaScript:

 // Generate range from start (inclusive) to stop (exclusive): function* range(start, stop, step = 1) { if (stop === undefined) [start, stop] = [0, start]; if (step > 0) while (start < stop) yield start, start += step; else if (step < 0) while (start > stop) yield start, start += step; else throw new RangeError('range() step argument invalid'); } // Examples: console.log([...range(3)]); // [0, 1, 2] console.log([...range(0, 3)]); // [0, 1, 2] console.log([...range(0, 3, -1)]);// [] console.log([...range(0, 0)]); // [] console.log([...range(-3)]); // [] console.log([...range(-3, 0)]); // [-3, -2, -1] 

It supports any argument that can be compared with 0 and stop and can be increased by step . It behaves identically to the Python version when used with numbers not exceeding Number.MAX_SAFE_INTEGER .

Pay attention to the following corner cases:

 [...range(0, 0, 0)]; // RangeError: range() step argument invalid [...range(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 2)]; // [] [...range(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 3)]; // Infinite loop [...range(0.7, 0.8, 0.1)]; // [0.7, 0.7999999999999999] [...range('1', '11')]; // ['1'] [...range('2', '22')]; // Infinite loop 

Unlike @Tadeck , @ Volv's, and @ janka102 , which return [] , undefined or enter an infinite loop when step evaluates to 0 or NaN , this generator function throws an exception similar to Python behavior.

+5
Mar 27 '17 at 19:11
source share

To get an array of size x here is single-line without using a library

 var range = n => Array(n + 1).join(1).split('').map((x, i) => i) 

works like

 > range(4) [0, 1, 2, 3] 
+4
Mar 23 '16 at 15:52
source share

It is further refined with ES6 default parameters.

 let range = function*(start = 0, stop, step = 1) { let cur = (stop === undefined) ? 0 : start; let max = (stop === undefined) ? start : stop; for (let i = cur; step < 0 ? i > max : i < max; i += step) yield i } 
+3
Feb 22 '16 at 21:47
source share

You can use the underscore library. It contains dozens of useful functions for working with arrays and many others.

+2
Aug 24 '14 at 10:58
source share

pythonic mimics Python's range behavior in the best possible way using JS ( yield ) generators, supporting range(stop) and range(start, stop, step) use cases. In addition, the pythonic range function returns a custom Generator object that supports map and filter , so you can create single-line strings such as:

 import {range} from 'pythonic'; // ... const results = range(5).map(wouldBeInvokedFiveTimes); // 'results' is now an array containing elements from // 5 calls to wouldBeInvokedFiveTimes 

Install using npm :

 npm install --save pythonic 

Here is the pythonic code for the range:

 function range(...args) { if (args.length < 2) { return new Generator(rangeGeneratorWithStop(...args)); } return new Generator(rangeGeneratorWithSartAndStopAndStep(...args)); } const rangeGeneratorWithStop = stop => function * () { for (let i = 0; i < stop; i++) { yield i; } }; const rangeGeneratorWithSartAndStopAndStep = (start, stop, step = 1) => function * () { for (let i = start; i < stop; i += step) { yield i; } }; function range(...args) { if (args.length < 2) { return new Generator(rangeGeneratorWithStop(...args)); } return new Generator(rangeGeneratorWithSartAndStopAndStep(...args)); } class Generator { constructor(generatorFn) { this[Symbol.iterator] = generatorFn; } map(callbackFn) { const result = []; for (const element of this) { result.push(callbackFn(element)); } return result; } filter(callbackFn) { const result = []; for (const element of this) { if (callbackFn(element)) { result.push(element); } } return result; } toArray() { return Array.from(this); } } 

Disclosure I am the author and maintainer of Pythonic

+1
Apr 04 '18 at 4:12
source share

There is still no built-in function equivalent to range() , but with the latest version - ES2015 - you can create your own implementation. Here is a limited version. Limited because it does not take into account the step parameter. Min only, max.

const range = (min = null, max = null) => Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)

This is done using the Array.from method, which can build an array from any object that has the length property. Thus, passing a simple object using only the length property will create an ArrayIterator that will give length number of objects.

0
Aug 11 '16 at 6:14
source share

Here's another es6 range es6

 // range :: (from, to, step?) -> [Number] const range = (from, to, step = 1) => { //swap values if necesery [from, to] = from > to ? [to, from] : [from, to] //create range array return [...Array(Math.round((to - from) / step))] .map((_, index) => { const negative = from < 0 ? Math.abs(from) : 0 return index < negative ? from + index * step : (index - negative + 1) * step }) } range(-20, 0, 5) .forEach(val => console.log(val)) for(const val of range(5, 1)){ console.log('value ${val}') } 
0
Jan 08 '18 at 10:00
source share

MDN recommends this approach: sequence generator (range)

0
Apr 22 '19 at 20:44 on
source share

No, no, but you can do one.

I am partial to range behavior in Python3. Below you will find the JavaScript implementation of Python range ():

 function* range(start=0, end=undefined, step=1) { if(arguments.length === 1) {end = start, start = 0} [...arguments].forEach(arg => { if( typeof arg !== 'number') {throw new TypeError("Invalid argument")} }) if(arguments.length === 0) {throw new TypeError("More arguments neede")} if(start >= end) return yield start yield* range(start + step, end, step) } // Use Cases console.log([...range(5)]) console.log([...range(2, 5)]) console.log([...range(2, 5, 2)]) console.log([...range(2,3)]) // You can, of course, iterate through the range instance. 
0
May 26 '19 at 17:19
source share



All Articles