6

I have an array with a specified length and I'm trying to populate it with values that are dependent on each index.

let arr = new Array(someLength)
arr.map((v, i) => i * 2)

From what I know, this isn't working because map skips undefined values.

I have a few questions:

  1. Why does map work on something like [undefined, undefined]?
  2. Is there anyway to accomplish this using ES6 array methods?

    I know I can use a standard for loop, but was wondering if there's a nicer way to do it.

    for (let i = 0; i < arr.length; i++) { 
       arr[i] = i * 2 
    }
    

    I've found one method so far, it's not really clean though.

    arr = arr.fill(undefined).map((foo, i) => i * 2)
    
mdn
  • 93
  • 2
  • 5
  • Have you tried anything with every()? – GMaiolo Jul 02 '16 at 16:54
  • 1
    `.map()` doesn't skip undefined values; it skips undefined properties/members. –  Jul 02 '16 at 16:55
  • 1
    `[...Array(someLength)].map((_, i) => i * 2)` is another possibility. –  Jul 02 '16 at 16:58
  • 3
    It is more correct to say that `map` skips **missing** elements, or **holes**. By the way, no need to say `fill(undefined)`--just `fill()` is fine. –  Jul 02 '16 at 17:18
  • 1
    Possible duplicate of [Javascript Array map “appears” to execute callback on missing elements](http://stackoverflow.com/q/35044451/1529630) and [JavaScript “new Array(n)” and “Array.prototype.map” weirdness](http://stackoverflow.com/q/5501581/1529630) – Oriol Jul 02 '16 at 17:39

3 Answers3

12
  1. Why does .map work on something like [undefined, undefined]?

Consider these two scenarios

let a1 = [];
a1.length = 2;
a1; // [undefined × 2]

// vs

let a2 = [undefined, undefined];
a2; // [undefined, undefined]

What would be the result of Object.keys on each of these?

Object.keys(a1); // []
Object.keys(a2); // ["0", "1"]

So, we can see the difference between the two - one has initialised keys, the other doesn't


  1. Is there anyway to accomplish this using ES6 array methods?

You already pointed out .fill, you could also use Array.from

Array.from({length: 5}, (itm, idx) => 2 * idx); // [0, 2, 4, 6, 8]
Paul S.
  • 64,864
  • 9
  • 122
  • 138
1

You could generate an array with undefined values.

Array.apply(null, {length: 5})

and use it for the mapping.

var array = Array.apply(null, {length: 5});
console.log(array);

array = array.map((_, i) => 2 * i);
console.log(array);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You just have to fill the array with 0. Then you could process with map or forEach like this :

var arr = new Array(5); //[,,,,,]
arr.fill(0).forEach((v, i, tab) => {tab[i] = i * 2}); // [ 0, 2, 4, 6, 8 ]
kevin ternet
  • 4,514
  • 2
  • 19
  • 27