3

Is it any way to create an array a selected size(for example 10) and immediately on the spot fill in it with some numbers specified pattern (1, 2, 3, OR 2, 4, 6 and so on) in one statement in JS?

let arr = new Array(10).fill( (a) => {a = 1; return a++; } );
console.log(arr); // Should be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

In other words can I pass a some patern or function to method fill insted of a single value.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Yellowfun
  • 418
  • 1
  • 9
  • 21

1 Answers1

12

Actually there's much nicer idiom to create ranges: a spreaded Array constructor:

[...Array(n)]

creates an array of n undefined values. To get 0..n-1, just pick its keys:

[...Array(n).keys()]

for arbitrary ranges, feed it to map:

r = [...Array(10)].map((_, i) => i + 1)

console.log(r)

see here: Does JavaScript have a method like "range()" to generate an array based on supplied bounds?

old answer:

yep, you're looking for Array.from:

r = Array.from({length: 10}, (_, i) => i + 1);

console.log(r)

How does this work? .from inspects its first argument (which can be any object) and picks its .length property. Then, it iterates from 0 to length - 1 and invokes the second argument with two parameters - a value (which is undefined unless the first argument contains a corresponding numeric property) and an index, which takes values from 0...length-1. In this example, we have a function that just returns an index + 1, thus giving us 1..length.

Here's a useful wrapper for the above:

let range = (from, to) => Array.from({length: to - from + 1}, _ => from++);

console.log(range(1, 10))

For ES5, the idiom is Array.apply(null, {length:N}):

r = Array.apply(null, {length: 10}).map(function(_, i) {
    return i + 1
})
georg
  • 211,518
  • 52
  • 313
  • 390
  • 1
    What is the ES5 equivalent of this? I tried `Array.prototype.slice.call({length:10})` but it has the same behaviour as `Array(10)` – Pavlo Feb 24 '18 at 12:39
  • 1
    @Pavlo: There is none, that's why it was added. :-) But it's trivial to polyfill. – T.J. Crowder Feb 24 '18 at 12:40
  • 1
    @T.J.Crowder I found it `Array.apply(null, Array(10))` – Pavlo Feb 24 '18 at 12:40
  • 1
    @Pavlo: That doesn't do what `Array.from` does. (But it does create an array filled with `undefined`). So to get the `Array.from` you'd add `.map` on the end: `Array.apply(null, Array(10)).map(function(_, i) { return i + 1; });` Obviously this is slightly less efficient than a real polyfill would be, as it creates and throws away two arrays. – T.J. Crowder Feb 24 '18 at 12:42
  • 1
    @Pavlo: added... – georg Feb 24 '18 at 12:43
  • @T.J.Crowder Yes i know, i was more looking for how to create an array of undefined of a given a length, the second argument of `from` is super nice, and probably avoids O(n*2) in order to fill the array – Pavlo Feb 24 '18 at 12:44
  • @Slai doesn't work creating empty x 10 doesn't work with map, probably because it doesn't iterate, when its `[undefined, undefined, undefined, ...]` it works – Pavlo Feb 24 '18 at 12:48
  • yes my bad .. the good old for loop can be used on older browsers or for better performance – Slai Feb 24 '18 at 12:51