Array.map doesn't seem to work on uninitialized arrays

I'm trying to set default values on an uninitialized array using the map function but it doesn't seem to work, any ideas on how to set default values?

Consider this code snippet I tried in Chrome console.

> var N = 10;
> var x = new Array(N);
> x
  [undefined x 10]

> x.map(function(i) { return 0;});
  [undefined x 10]

I was expecting the array to be initialized to 0's.

Answers:

Answer

If you'd like to fill an array, you can use Array(5).fill() and the methods will then work as expected--see the alternate related answer from aasha7. Older pre-fill approaches include:

Array.apply(null, new Array(5)).map(function() { return 0; });
// [ 0, 0, 0, 0, 0 ]

After some reading one of the posts linked in the comments, I found this can also be written as

Array.apply(null, {length: 5}).map(function() { return 0; });

However, trying to use .map on undefined values will not work.

x = new Array(10);
x.map(function() { console.log("hello"); });

// so sad, no "hello"
// [ , , , , , , , , ,  ]

.map will skip over undefined values :(

Answer

I'd just like to point out that you can now do:

Array(2).fill().map(_ => 4);

This will return [4, 4].

Answer

That's how it's described by the ECMAScript Language specification

Here's the relevant part of Array.prototype.map, as described by (§15.4.4.19)

  • ...
  • 8. Repeat, while k < len
    • a) Let Pk be ToString(k).
    • b) Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument Pk.
    • c) If kPresent is true, then
      • do the magic
  • ...

Since there is no initilized member in your array, calling e.g new Array (1337).hasOwnProperty (42)evaluates to false, hence the condition in step 8.c is not met.

You can however use a little "hack" to do what you want.

Array.apply(null, { length: 5 }).map(Number.call, Number) //[0, 1, 2, 3, 4]

How this works has been thouroughly explained by @Zirak

Answer

The .map() function skips entries that have never been assigned values. Thus on a newly-constructed array like yours, it does essentially nothing.

Here is the MDN description.

Answer

With .map(), undefined elements are skipped and not passed to the callback so if you have an array with no elements that actually contain anything, then the callback is never called.

From the ECMA script 262, 5.1 specification, section 15.4.4.19:

callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

Answer

You can populate an array with zeros using this function:

function fillArrayWithNumber(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return 0; });
}

fillArrayWithNumber(5); // [0,0,0,0,0]

Or with a small change you can use indexes instead:

function fillArrayWithIndex(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return i; });
}

fillArrayWithIndex(5); // [0,1,2,3,4]

Fiddle

Answer

Building on a previous answer there is new shorter syntax. The OP wanted to create an array of N items initialized with 0.

var N = 10;
var x = new Array(N).fill(0);
// x is now: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

You also don't need the new - it's optional in this context.

Check the compatibility of your target platform and/or use a pollyfill if not available.

Answer

Also possible solution without Array.prototype.fill:

[...Array(10)].map((_, idx) => idx); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.