0

I'm trying to generate an array. Here's a simplified snippet of where I'm having a problem:

//should return an array with 10 elements with values of 0
var arr = Array(10).map(function() {return 0;});

console.log(arr.length); //returns 10
console.log(arr); //empty array

I understand that using Array(length) returns an array with length elements that are set to undefined. I suspect .map() is skipping over undefined elements, but am not 100% sure about it.

What can I do to get the intended results? I know I can accomplish the same thing with a loop, but I would really like to use .map() if possible.

--Update--

Can anyone explain why this works?

var arr = Array(10).join().split(',').map(function() {return 0;});

-edit- Disregard the update. I figured out why it works.

  • There are no members in that Array. The iterator methods perform a `if (i in this)` check on every iteration to make sure the member actually exists as an own or inherited property. – cookie monster Aug 27 '14 at 03:17
  • 3
    You can do `Array.apply(null, Array(10))` to force creation of members. The `.apply()` method doesn't care if the collection given has actual members or not. – cookie monster Aug 27 '14 at 03:18
  • @cookiemonster You should add that as the answer :) . –  Aug 27 '14 at 03:19
  • I left an answer on [this question](http://stackoverflow.com/questions/23460301/foreach-on-array-of-undefined-created-by-array-constructor), but received 2 down votes, so I'll let someone else handle it. *(I also put the same `.apply()` solution in a comment since that question was just about the "why" part.)* – cookie monster Aug 27 '14 at 03:23
  • And FYI, ECMAScript 6 is going to have an `Array.prototype.fill()` method, so you could do `Array(5).fill(0);` to handle a zero initialized Array. It works right now in FireFox. – cookie monster Aug 27 '14 at 03:31
  • Yes, `map` skips over undefined elements. Consider the case of `var arr = []; arr[1000000] = 1; arr.map(...);`--we certainly don't want an array of one million elements coming back. Same holds for the other `Array.prototype` methods such as `forEach`. –  Aug 27 '14 at 03:31
  • @torazaburo the problem lies in the fact that the constructor does not really assign values to `N` indices, once you use apply as stated above and below, you can use these methods and actually loop `N` times (reduce, reduceRight, filter, map, forEach, some, and every, etc.) – axelduch Aug 27 '14 at 03:38

2 Answers2

0

Array.apply may accepts an object that can have a property length and based on it, push undefined length times in it.

For instance:

Array.apply(null, {length: 10});

Which explains why you can also use cookie monster's suggestion:

Array.apply(null, Array(10));

Because Array(10) will create property length with a value of 10 as expected.

Community
  • 1
  • 1
axelduch
  • 10,769
  • 2
  • 31
  • 50
0

In modern JavaScript, you'd solve this with fill (for static values) or Array.from using its mapping callback (if the values vary).

Static values -- fill:

const arr = Array.from({length: 10}).fill(0);
console.log(arr);

Varying values -- Array.from:

const arr = Array.from({length: 10}, () => Math.random());
console.log(arr);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875