1

I've been playing around with generating image filters using canvas, and I was attempting to improve speed by preallocating an entire matrix from the beginning.

This code was the first thing that I tried:

var N = 3
var matrix = new Array(N).map(function () { return new Array(N) })
// [ undefined x 3 ]

unfortunately, this doesn't do what I expect.

My expected result is given by this code:

N = 3;
matrix = [undefined,undefined,undefined].map(function () { return new Array(N) })
// [Array[3], Array[3], Array[3]]

Obviously, the preallocation can be done another way. This seems like it probably occurs due to some corner cutting done for performance in the implementation of javascript.

Anyone know why the first example doesn't do the same thing as the second?

Environments Checked:

OS: OSX Yosemite

Browsers: Chrome, Firefox Dev (same thing from both)

Potter
  • 633
  • 7
  • 13

1 Answers1

3

The problem is that new Array(n), as well as Array(n) (which are equivalent) creates a sparse array. Unfortunately, functions like .forEach and .map do not iterate over sparse sections of arrays, which is why you're seeing that behavior.

There's a trick that you can use to initialize a dense array of a specific size:

> var arr = Array.apply(null, {length: N});
> console.log(arr);
[undefined, undefined, undefined]

And once you have a dense array, you can use .map properly:

var matrix = Array.apply(null, {length: N}).map(function() {
    return Array.apply(null, {length: N});
});
Community
  • 1
  • 1
voithos
  • 68,482
  • 12
  • 101
  • 116