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:
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]
Taken from Kyle Simpson's course Rethinking Asynchronous JavaScript
An option for NodeJs is to use a Buffer:
[...Buffer.alloc(5).keys()]
// [ 0, 1, 2, 3, 4 ]
What's nice is that you can iterate directly on the buffer:
Buffer.alloc(5).forEach((_, index) => console.log(index))
// 0
// 1
// 2
// 3
// 4
You can't do that with an uninitialized Array:
Array(5).forEach((_, index) => console.log(index))
// undefined
But, who in their right mind uses a Buffer for a purpose like this ;)
MDN recommends this approach: Sequence generator (range)
// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// Generate numbers range 0..4
console.log("range(0, 4, 1):", range(0, 4, 1));
// [0, 1, 2, 3, 4]
// Generate numbers range 1..10 with step of 2
console.log("\nrange(1, 10, 2):", range(1, 10, 2));
// [1, 3, 5, 7, 9]
// Generate the alphabet using Array.from making use of it being ordered as a sequence
console.log("\nrange('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x))", range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x)));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
Assuming you need a simple range with a single step:
let range = (start, end)=> {
if(start === end) return [start];
return [start, ...range(start + 1, end)];
}
else
let range = (start, end, step)=> {
if(start === end) return [start];
return [start, ...range(start + step, end)];
}
refer to here for more.
Still no built-in function that is equivalent to range()
, but with the most recent version - ES2015 - you can build your own implementation. Here's a limited version of it. Limited because it doesn't take into account the step parameter. Just min, max.
const range = (min = null, max = null) =>
Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)
This is accomplished by the Array.from
method able to build an array from any object that has a length
property. So passing in a simple object with just the length
property will create an ArrayIterator that will yield length
number of objects.
Here you go.
This will write (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 don't provide a number, it will use the current length of the Array.
Use it like this:
var array = [].writeIndices(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]