Is there a function in JavaScript similar to Python\'s range()
?
I think there should be a better way than to write the following lines every time:
Is there a function in JavaScript similar to Python's range()?
As answered before: no, there's not. But you can make your own.
I believe this is an interesting approach for ES6. It works very similar to Python 2.7 range()
, but it's much more dynamic.
function range(start, stop, step = 1)
{
// This will make the function behave as range(stop)
if(arguments.length === 1)
{
return [...Array(arguments[0]).keys()]
}
// Adjusts step to go towards the stop value
if((start > stop && !(step < 0)) ||
(start < stop && !(step > 0)))
{
step *= -1
}
let returnArray = []
// Checks if i is in the interval between start and stop no matter if stop
// is lower than start or vice-versa
for(let i = start; (i-start)*(i-stop) <= 0; i += step)
{
returnArray.push(i)
}
return returnArray
}
This function can behave in three different ways (just like Python's range()):
range(stop)
range(start, stop)
range(start, stop, step)
These examples:
console.log(range(5))
console.log(range(-2, 2))
console.log(range(2, -2))
console.log(range(10, 20, 2))
Will give you the following output:
[ 0, 1, 2, 3, 4 ]
[ -2, -1, 0, 1, 2 ]
[ 2, 1, 0, -1, -2 ]
[ 10, 12, 14, 16, 18, 20 ]
Note that instead of iterating over the array with the in
operator (like python), you have to use of
. Thus the i
variable assumes the value, and not the index, of the array's element.
for(let i of range(5))
{
// do something with i...
}
Fusing together both answers from @Tadeck and @georg, I came up with this:
function* range(start, stop, step = 1) {
if (stop == null) {
// 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 the ES6/JS1.7 for-of loop:
for (let i of range(5)) {
console.log(i);
}
// Outputs => 0 1 2 3 4
for (let i of range(0, 10, 2)) {
console.log(i);
}
// Outputs => 0 2 4 6 8
for (let i of range(10, 0, -2)) {
console.log(i);
}
// Outputs => 10 8 6 4 2
Here's how i do it
let n = 5
[...Array(n).keys()].map(x=>{console.log(x)})
output
0
1
2
3
4
No, there is none, but you can make one.
I'm partial to Python3 behavior of range. You will find below JavaScript's implementation of Python's 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.
pythonic mimics the Python range
behaviour best it can using JS' generators (yield
), supporting both the range(stop)
and range(start, stop, step)
use cases. In addition, pythonic
's range
function returns an Iterator
object similar to Python that supports map
and filter
, so one could do fancy one-liners like:
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
Disclosure I'm author and maintainer of Pythonic
You may use underscore library. It contains dozens of useful functions for working with arrays and many more.