I have been reading online and some places say it isn\'t possible, some say it is and then give an example and others refute the example, etc.
How do I dec
Below one, creates a 5x5 matrix and fill them with null
var md = [];
for(var i=0; i<5; i++) {
md.push(new Array(5).fill(null));
}
console.log(md);
In JavaScript 1.7 and higher you can use array comprehensions to create two dimensional arrays. You can also filter and/or manipulate the entries while filling the array and don't have to use loops.
var rows = [1, 2, 3];
var cols = ["a", "b", "c", "d"];
var grid = [ for (r of rows) [ for (c of cols) r+c ] ];
/*
grid = [
["1a","1b","1c","1d"],
["2a","2b","2c","2d"],
["3a","3b","3c","3d"]
]
*/
You can create any n x m
array you want and fill it with a default value by calling
var default = 0; // your 2d array will be filled with this value
var n_dim = 2;
var m_dim = 7;
var arr = [ for (n of Array(n_dim)) [ for (m of Array(m_dim) default ]]
/*
arr = [
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
]
*/
More examples and documentation can be found here.
Please note that this is not a standard feature yet.
Today 2020.02.05 I perform tests on MacOs HighSierra 10.13.6 on Chrome v79.0, Safari v13.0.4 and Firefox v72.0, for chosen solutions.
Conclusions for non-initialised 2d array
{}/arr[[i,j]]
(N) is fastest for big and small arrays and it looks like it is good choice for big sparse arraysfor-[]/while
(A,G) are fast and they are good choice for small arrays.for-[]
(B,C) are fast and they are good choice for big arraysArray..map/from/fill
(I,J,K,L,M) are quite slow for small arrays, and quite fast for big arraysfor-Array(n)
(B,C) is much slower on safari than for-[]
(A)for-[]
(A) for big array is slow on all browsersConclusions for initialised 2d array
for/while
(A,B,C,D,E,G) are fastest/quite fast for small arrays on all browsersfor
(A,B,C,E) are fastest/quite fast for big arrays on all browsersArray..map/from/fill
(I,J,K,L,M) are medium fast or slow for small arrays on all browsers{}/arr[[i,j]]
(N) is slowest for small and big arrays on all browsersTest for solutions which not fill (initialise) output array
We test speed of solutions for
function A(r) {
var arr = [];
for (var i = 0; i < r; i++) arr[i] = [];
return arr;
}
function B(r, c) {
var arr = new Array(r);
for (var i = 0; i < arr.length; i++) arr[i] = new Array(c);
return arr;
}
function C(r, c) {
var arr = Array(r);
for (var i = 0; i < arr.length; i++) arr[i] = Array(c);
return arr;
}
function D(r, c) {
// strange, but works
var arr = [];
for (var i = 0; i < r; i++) {
arr.push([]);
arr[i].push(Array(c));
}
return arr;
}
function E(r, c) {
let array = [[]];
for (var x = 0; x < c; x++) {
array[x] = [];
for (var y = 0; y < r; y++) array[x][y] = [0];
}
return array;
}
function F(r, c) {
var makeArray = function(dims, arr) {
if (dims[1] === undefined) {
return Array(dims[0]);
}
arr = Array(dims[0]);
for (var i = 0; i < dims[0]; i++) {
arr[i] = Array(dims[1]);
arr[i] = makeArray(dims.slice(1), arr[i]);
}
return arr;
}
return makeArray([r, c]);
}
function G(r) {
var a = [];
while (a.push([]) < r);
return a;
}
function H(r,c) {
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args);
}
return arr;
}
return createArray(r,c);
}
function I(r, c) {
return [...Array(r)].map(x => Array(c));
}
function J(r, c) {
return Array(r).fill(0).map(() => Array(c));
}
function K(r, c) {
return Array.from(Array(r), () => Array(c));
}
function L(r, c) {
return Array.from({length: r}).map(e => Array(c));
}
function M(r, c) {
return Array.from({length: r}, () => Array.from({length: c}, () => {}));
}
function N(r, c) {
return {}
}
// -----------------------------------------------
// SHOW
// -----------------------------------------------
log = (t, f) => {
let A = f(3, 4); // create array with 3 rows and 4 columns
A[1][2] = 6 // 2-nd row 3nd column set to 6
console.log(`${t}[1][2]: ${A[1][2]}, full: ${JSON.stringify(A).replace(/null/g,'x')}`);
}
log2 = (t, f) => {
let A = f(3, 4); // create array with 3 rows and 4 columns
A[[1,2]] = 6 // 2-nd row 3nd column set to 6
console.log(`${t}[1][2]: ${A[[1,2]]}, full: ${JSON.stringify(A).replace(/null/g,'x')}`);
}
log('A', A);
log('B', B);
log('C', C);
log('D', D);
log('E', E);
log('F', F);
log('G', G);
log('H', H);
log('I', I);
log('J', J);
log('K', K);
log('L', L);
log('M', M);
log2('N', N);
This is presentation of solutions - not benchmark
Test for solutions which fill (initialise) output array
We test speed of solutions for
function A(r, c, def) {
var arr = [];
for (var i = 0; i < r; i++) arr[i] = Array(c).fill(def);
return arr;
}
function B(r, c, def) {
var arr = new Array(r);
for (var i = 0; i < arr.length; i++) arr[i] = new Array(c).fill(def);
return arr;
}
function C(r, c, def) {
var arr = Array(r);
for (var i = 0; i < arr.length; i++) arr[i] = Array(c).fill(def);
return arr;
}
function D(r, c, def) {
// strange, but works
var arr = [];
for (var i = 0; i < r; i++) {
arr.push([]);
arr[i].push(Array(c));
}
for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[i][j]=def
return arr;
}
function E(r, c, def) {
let array = [[]];
for (var x = 0; x < c; x++) {
array[x] = [];
for (var y = 0; y < r; y++) array[x][y] = def;
}
return array;
}
function F(r, c, def) {
var makeArray = function(dims, arr) {
if (dims[1] === undefined) {
return Array(dims[0]).fill(def);
}
arr = Array(dims[0]);
for (var i = 0; i < dims[0]; i++) {
arr[i] = Array(dims[1]);
arr[i] = makeArray(dims.slice(1), arr[i]);
}
return arr;
}
return makeArray([r, c]);
}
function G(r, c, def) {
var a = [];
while (a.push(Array(c).fill(def)) < r);
return a;
}
function H(r,c, def) {
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args).fill(def);
}
return arr;
}
return createArray(r,c);
}
function I(r, c, def) {
return [...Array(r)].map(x => Array(c).fill(def));
}
function J(r, c, def) {
return Array(r).fill(0).map(() => Array(c).fill(def));
}
function K(r, c, def) {
return Array.from(Array(r), () => Array(c).fill(def));
}
function L(r, c, def) {
return Array.from({length: r}).map(e => Array(c).fill(def));
}
function M(r, c, def) {
return Array.from({length: r}, () => Array.from({length: c}, () => def));
}
function N(r, c, def) {
let arr={};
for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[[i,j]]=def;
return arr;
}
// -----------------------------------------------
// SHOW
// -----------------------------------------------
log = (t, f) => {
let A = f(1000,1000,7); // create array with 1000 rows and 1000 columns,
// each array cell initilised by 7
A[800][900] = 5 // 800nd row and 901nd column set to 5
console.log(`${t}[1][2]: ${A[1][2]}, ${t}[800][901]: ${A[800][900]}`);
}
log2 = (t, f) => {
let A = f(1000,1000,7); // create array with 1000 rows and 1000 columns,
// each array cell initilised by 7
A[[800,900]] = 5 // 800nd row 900nd column set to 5
console.log(`${t}[1][2]: ${A[[1,2]]}, ${t}[800][900]: ${A[[800,900]]}`);
}
log('A', A);
log('B', B);
log('C', C);
log('D', D);
log('E', E);
log('F', F);
log('G', G);
log('H', H);
log('I', I);
log('J', J);
log('K', K);
log('L', L);
log('M', M);
log2('N', N);
This is presentation of solutions - not benchmark
To create a non-sparse "2D" array (x,y) with all indices addressable and values set to null:
let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null)))
bonus "3D" Array (x,y,z)
let 3Darray = new Array(x).fill(null).map(item=>(new Array(y).fill(null)).map(item=>Array(z).fill(null)))
Variations and corrections on this have been mentioned in comments and at various points in response to this question but not as an actual answer so I am adding it here.
It should be noted that (similar to most other answers) this has O(x*y) time complexity so it probably not suitable for very large arrays.
There is another solution, that does not force you to pre-define the size of the 2d array, and that is very concise.
var table = {}
table[[1,2]] = 3 // Notice the double [[ and ]]
console.log(table[[1,2]]) // -> 3
This works because, [1,2]
is transformed into a string, that is used as a string key for the table
object.
The easiest way:
var arr = [];
var arr1 = ['00','01'];
var arr2 = ['10','11'];
var arr3 = ['20','21'];
arr.push(arr1);
arr.push(arr2);
arr.push(arr3);
alert(arr[0][1]); // '01'
alert(arr[1][1]); // '11'
alert(arr[2][0]); // '20'