51

How do I create an empty 2D array in Javascript (without knowing how many rows or columns there will be in the new array)?

If it's a simple array var newArray = new Array(); I can assign as many elements as I want. But what about a 2D array? Can I create one without specifying the numbers of rows and columns? and how do I access the elements afterwards (myArray[0][1] or myArray[0,1])?

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
meks
  • 777
  • 3
  • 12
  • 23
  • 1
    duplicate of: http://stackoverflow.com/questions/6495187/best-way-to-generate-empty-2d-array http://stackoverflow.com/questions/7521796/is-it-possible-to-create-an-empty-multidimensional-array-in-javascript-jquery and many more – K_B May 12 '13 at 21:24
  • I assumed that `var row_major = Array(height).map(function () { return Array(width); });` would do the trick, but finally needed a 2D array today and found that it doesn't. Damn. – Mark K Cowan Jun 11 '14 at 18:51

10 Answers10

101

You can create a 6 x 6 empty array like this:

var myGrid = [...Array(6)].map(e => Array(6));
  • Array(6) generates an array with length = 6 and full of undefined values.
  • We map that array to another array full of undefined values.
  • In the end, we get a 6x6 grid full of undefined positions.

If you need to initialize the grid with a default value:

var value = 'foo'; // by default
var myGrid = [...Array(6)].map(e => Array(6).fill(value));

Now you have a 6 x 6 grid full of 'foo'.

André
  • 12,497
  • 6
  • 42
  • 44
  • 10
    Underrated trick right here ^^^ works great for arbitrary 2D arrays. Here it is in reusable form: `const create2dArray = (rows, columns) => [...Array(rows).keys()].map(i => Array(columns)) ` – rkd Jun 10 '17 at 19:19
  • 3
    Further explanations would be nice ;) – TOPKAT Jan 16 '18 at 22:36
  • 5
    What is the point of using `[...Array(6)]` instead of just `Array(6)`? – nog642 May 28 '19 at 17:47
  • 5
    @nog642 you cannot iterate the array resulting of `Array(6)` because it has no elements, but the array resulting of `[...Array(6)]` contains 6 undefined elements and you can iterate/map them – André May 28 '19 at 21:30
  • 2
    You don't need the `e` in the map function. You can use empty parenthesis: `.map( () => Array(6).fill(value)` – Badrush Nov 20 '19 at 03:45
38

Yes you can create an empty array and then push data into it. There is no need to define the length first in JavaScript.
Check out jsFiddle Live Demo

Define:

const arr = [[],[]];

Push data:

arr[0][2] = 'Hi Mr.A';
arr[1][3] = 'Hi Mr.B';

Read data:

alert(arr[0][2]);
alert(arr[1][3]);

Update:

Here is also a video recommended by Brady Dowling:
Create a 2D array: ([https://www.youtube.com/watch?v=tMeDkp1J2OM][2])
Siamak Motlagh
  • 5,028
  • 7
  • 41
  • 65
14

There are no two dimensional arrays in Javascript.

To accomplish the effect of a two dimensional array, you use an array of arrays, also known as a jagged array (because the inner arrays can have different length).

An empty jagged array is created just like any other empty array:

var myArray = new Array();

You can also use an empty array literal:

var myArray = [];

To put any items in the jagged array, you first have to put inner arrays in it, for example like this:

myArray.push([]);
myArray[0][0] = 'hello';

You can also create an array that contains a number of empty arrays from start:

var myArray = [[],[],[]];

That gives you a jagged array without any items, but which is prepared with three inner arrays.

As it's an array of arrays, you access the items using myArray[0][1].

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
14

Say you wanted to make a 2d array (i.e. matrix) that's 100x100, you can do it in one line, like this:

var 2darray = new Array(100).fill(null).map(()=>new Array(100).fill(null));

This will create a 100x100 matrix of NULL's. Replace the 100x100 with whatever dimensions you want, and the null's with whatever is your prefered default value, or blank for undefined.

Noah Ellman
  • 179
  • 1
  • 4
4

You can use a simple for loop to create an array of the approximate size and then push more rows if need be.

const arr = [];
const n = 7;
const m = 5;

for (let i = 0; i < n; i++) {
    arr.push(new Array(m).fill(0));
}

const arr = [];
const n = 7;
const m = 5;

for (let i = 0; i < n; i++) {
    arr.push(new Array(m).fill(0));
}

console.log(arr);
3

The functions I use

function get_empty_2d_array(numRows, numColumnns) {
  return [...Array(numRows)].map(e => Array(numColumnns));
}

function get_2d_array_filled(numRows, numColumnns, fillValue) {
  return [...Array(numRows)].map(e => Array(numColumnns).fill(fillValue));
}
Valentin
  • 109
  • 1
  • 5
  • Welcome to Stack Overflow. Code dumps without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please [edit] your question and explain how it works better than what the OP provided. See [answer]. – ChrisGPT was on strike Mar 07 '21 at 19:44
2
var myArray = [
    ["cats","dogs","monkeys","horses"],
    ["apples","oranges","pears","bananas"]
];
document.write(myArray[0][2]) //returns "monkeys"
Qvcool
  • 460
  • 3
  • 10
2

Two things:

1) The array length property improperly reports the array length if called after the var myArray = [[],[]]; statement. Technically, since the empty arrays are defined, they are getting counted by the length property, but in the spirit of the length property it really should return 0, because no non-empty elements have been added to any of the arrays.

A minimum work around is to use two nested for( in ) loops, one for the 1st array and one for the 2nd array, and to count the non-undefined elements.

2) Extending Siamak A.Motlagh example and adding a arr([2][4]) = 'Hi Mr.C'; assignment fails with an "Uncaught TypeError: Cannot set property '4' of undefined" error.

See the jsFiddle: http://jsfiddle.net/howardb1/zq8oL2ds/

Here is a copy of that code:

var arr = [[],[]];

alert( arr.length );  // wrong!

var c = 0;
for( var i in arr )
  for( var j in arr[ i ] )
    if( arr[ i ][ j ] != undefined )
      ++c;
alert( c );  // correct

arr[0][2] = 'Hi Mr.A';
alert(arr[0][2]);

arr[1][3] = 'Hi Mr.B';
alert(arr[1][3]);

arr[2][4] = 'Hi Mr.C';  // At this point I'm getting VM558:62 Uncaught TypeError: Cannot set property '4' of undefined
alert(arr[2][4]);

var c = 0;
for( var i in arr )
  for( var j in arr[ i ] )
    if( arr[ i ][ j ] != undefined )
      ++c;
alert( c );

Why does the third assignment fail? What about the [[],[]] creation statement told it that the first array was valid for 0 and 1, but not 2 or that 2 and 3 were ok for the second array, but not 4?

Most importantly, how would I define an Array in an Array that could hold date objects in the first and second arrays. I'm using the jQuery-UI DatePicker, which expects an array of dates, as in date objects, which I've extended to use a second date array to contain date objects that contain times so I can keep track of multiple dates, and multiple times per day.

Thanks.

  • Why does the third assignment fail? What about the [[],[]] creation statement told it that the first array was valid for 0 and 1, but not 2 or that 2 and 3 were ok for the second array, but not 4? This is my nightmare. – Mustafa May 09 '21 at 06:01
0

This also works as an expression:

var twoDarr= new Array(desiredLength);
for (i=0;i<twoDarr.length;i++) {twoDarr[i]=[];} 

I don't know how it pars in terms of performance with the rest of the answers here, if you have a clue let me know in the comments.

If you don't know the length of the array beforehand pls have in mind that you can use either push([]), or splice() if you want to push/remove/replace a new element in place of an existing one.

alexandros84
  • 321
  • 4
  • 14
-1
const grid = new Array(n).fill(new Array(n))
  • 9
    All the inner arrays will have the same reference. Changing one inner array will change all other inner arrays. In most cases, This is not the desired behavior. – Manish Menaria Jul 31 '20 at 10:50