How do you easily create empty matrices javascript?

Solution 1:

Array.fill

Consider using fill:

Array(9).fill().map(()=>Array(9).fill())

The idea here is that fill() will fill out the items with undefined, which is enough to get map to work on them.

You could also fill directly:

Array(9).fill(Array(9))

Alternatives to Array(9).fill() include

Array(...Array(9))
[].push(...Array(9))
[].concat(Array(9))
Array.from(Array(9))

We can rewrite the solution a bit more semantically as:

function array9() { return Array(9).fill(); }
array9().map(array9)

or

function array(n) { return Array(n).fill(); }
array(9).map(() => array(9))

Array.from provides us with an optional second mapping argument, so we have the alternative of writing

Array.from(Array(9), () => Array.from(Array(9));

or, if you prefer

function array9(map) { return Array.from(Array(9), map); }
array9(array9);

For verbose description and examples, see Mozilla's Docs on Array.prototype.fill() here.
and for Array.from(), here.

Note that neither Array.prototype.fill() nor Array.from() has support in Internet Explorer. A polyfill for IE is available at the above MDN links.

Partitioning

partition(Array(81), 9)

if you have a partition utility handy. Here's a quick recursive one:

function partition(a, n) {
  return a.length ? [a.splice(0, n)].concat(partition(a, n)) : [];
}  

Looping

We can loop a bit more efficiently with

var a = [], b;
while (a.push(b = []) < 9) while (b.push(null) < 9);

Taking advantage of the fact that push returns the new array length.

Solution 2:

var matrix = [];
for(var i=0; i<9; i++) {
    matrix[i] = new Array(9);
}

... or:

var matrix = [];
for(var i=0; i<9; i++) {
    matrix[i] = [];
    for(var j=0; j<9; j++) {
        matrix[i][j] = undefined;
    }
}

Solution 3:

There is something about Array.fill I need to mention.

If you just use below method to create a 3x3 matrix.

Array(3).fill(Array(3).fill(0));

You will find that the values in the matrix is a reference.

enter image description here


Optimized solution (prevent passing by reference):

If you want to pass by value rather than reference, you can leverage Array.map to create it.

Array(3).fill(null).map(() => Array(3).fill(0));

enter image description here

Solution 4:

// initializing depending on i,j:
var M=Array.from({length:9}, (_,i) => Array.from({length:9}, (_,j) => i+'x'+j))

// Print it:

console.table(M)
// M.forEach(r => console.log(r))
document.body.innerHTML = `<pre>${M.map(r => r.join('\t')).join('\n')}</pre>`
// JSON.stringify(M, null, 2) // bad for matrices

Beware that doing this below, is wrong:

// var M=Array(9).fill([]) // since arrays are sparse
// or Array(9).fill(Array(9).fill(0))// initialization

// M[4][4] = 1
// M[3][4] is now 1 too!

Because it creates the same reference of Array 9 times, so modifying an item modifies also items at the same index of other rows (since it's the same reference), so you need an additional call to .slice or .map on the rows to copy them (cf torazaburo's answer which fell in this trap)

note: It may look like this in the future, with Number.range() proposal

const M = [...Number.range(1,10)].map(i => [...Number.range(1,10)].map(j => i+'x'+j))