Having googled for it I found two solutions:
Further refinement, produces an array with value starting from 1:
Array.from(Array(10).keys(), n => n + 1)
A tour of Array.from thru practical examples
Array.from
also accepts a second argument which is used as a mapping function
let out = Array.from(Array(10), (_,x) => x);
console.log(out);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
This is nice to know because you might want to generate arrays that are sometimes more complex than just 0
thru N
.
const sq = x => x * x;
let out = Array.from(Array(10), (_,x) => sq(x));
console.log(out);
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Or you can make arrays out of generators, too
function* range(start, end, step) {
while (start < end) {
yield start;
start += step;
}
}
let out = Array.from(range(10,20,2));
console.log(out); // [10, 12, 14, 16, 18]
Array.from
is just massively powerful. People don't even realize its full potential yet.
const ord = x => x.charCodeAt(0);
const dec2hex = x => `0${x.toString(16)}`.substr(-2);
// common noob code
{
let input = "hello world";
let output = input.split('').map(x => dec2hex(ord(x)));
console.log(output);
// ["68", "65", "6c", "6c", "6f", "20", "77", "6f", "72", "6c", "64"]
}
// Array.from
{
let input = "hello world";
let output = Array.from(input, x => dec2hex(ord(x)));
console.log(output);
// ["68", "65", "6c", "6c", "6f", "20", "77", "6f", "72", "6c", "64"]
}
Here is a range
function which takes start
, end
, and a step
parameter. It returns an array starting a from start
upto (but excluding) the end
number with increments of size step
.
const range = (start, end, step) => {
return Array.from(Array.from(Array(Math.ceil((end-start)/step)).keys()), x => start+ x*step);
}
console.log(range(1, 10, 1));
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(0, 9, 3));
//[0, 3, 6]
console.log(range(10, 30, 5));
//[10, 15, 20, 25]
Taking a step further, if you want a range that includes the end
as well.
const inclusiveRange = (start, end, step) => {
return Array.from(Array.from(Array(Math.ceil((end-start+1)/step)).keys()), x => start+ x*step);
}
console.log(inclusiveRange(1, 10, 1));
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(inclusiveRange(0, 9, 3));
// [0, 3, 6, 9]
console.log(inclusiveRange(10, 30, 5));
//[10, 15, 20, 25, 30]
Here is a simple solution that works in codepen:
Array.from(Array(10).keys())
To be clear, Array.from()
and Array.keys()
require an ES6 polyfill in order to work in all browsers.
All of the other answers here create a temporary intermediate array, which isn't necessary.
Array.from({ length: 10 }, (_, i) => i)
This is essentially a map function where you map from array index to whatever you'd like, for any number of elements.
It seems the problem is that codepen precompiles your code using babel es2015-loose.
In that mode, your
[...Array(10).keys()];
becomes
[].concat(Array(10).keys());
And that's why you see an array containing an iterator.
With es2015 mode you would get
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
[].concat(_toConsumableArray(Array(10).keys()));
which would behave as desired.
See ②ality - Babel 6: loose mode for more information about the modes.