1411

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.

  1. How do I declare a 2 dimensional array in JavaScript? (assuming it's possible)

  2. How would I access its members? (myArray[0][1] or myArray[0,1]?)

12
  • 28
    Assuming a somewhat pedantic definition, it is technically impossible to create a 2d array in javascript. But you can create an array of arrays, which is tantamount to the same. Commented Jul 29, 2014 at 5:05
  • 24
    FYI... when you fill an array with more arrays using var arr2D = new Array(5).fill(new Array(3));, each element of Array(5) will point to the same Array(3). So it's best to use a for loop to dynamically populate sub arrays. Commented May 23, 2016 at 8:51
  • 95
    a = Array(5).fill(0).map(x => Array(10).fill(0)) Commented Mar 25, 2017 at 14:21
  • 5
    In other words, fill doesn't call new Array(3) for each index of the array being filled, since it's not a lambda expression or anything, such as Longfei Wu's comment above, which initially fills the array with 0's, then uses the map function with a lambda to fill each element with a new array. The fill function simply fills the array with exactly what you tell it to. Does that make sense? For more info on the map function, see: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Sep 16, 2017 at 5:38
  • 2
    @kalehmann that is fine: meta.stackoverflow.com/a/252017/2311074 If the new question is a better question or has better answers, then vote to close the old one as a duplicate of the new one. Commented Aug 14, 2019 at 6:49

56 Answers 56

1
2
5

Here's a quick way I've found to make a two dimensional array.

function createArray(x, y) { return Array.apply(null, Array(x)).map(e => Array(y)); } 

You can easily turn this function into an ES5 function as well.

function createArray(x, y) { return Array.apply(null, Array(x)).map(function(e) { return Array(y); }); } 

Why this works: the new Array(n) constructor creates an object with a prototype of Array.prototype and then assigns the object's length, resulting in an unpopulated array. Due to its lack of actual members we can't run the Array.prototype.map function on it.

However, when you provide more than one argument to the constructor, such as when you do Array(1, 2, 3, 4), the constructor will use the arguments object to instantiate and populate an Array object correctly.

For this reason, we can use Array.apply(null, Array(x)), because the apply function will spread the arguments into the constructor. For clarification, doing Array.apply(null, Array(3)) is equivalent to doing Array(null, null, null).

Now that we've created an actual populated array, all we need to do is call map and create the second layer (y).

Sign up to request clarification or add additional context in comments.

Comments

5

One liner to create a m*n 2 dimensional array filled with 0.

new Array(m).fill(new Array(n).fill(0)); 

2 Comments

Actually, this will create only two arrays. Second dimensions is going to be the same array in every index.
Yes, I confirm the gotcha. Quick fix: a = Array(m).fill(0).map(() => Array(n).fill(0)) ? map will untie reference and create unique array per slot.
5

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.

3 Comments

This answer alone makes me not want to mess with the junk that is "multi-dimensional" arrays in JavaScript, even tho I have a very elegant solution.This also illustrates that everyone else isn't actually making multidimensional arrays at all.Just like an "array" in JavaScript; this answer will completely "simulate" a pseudo-infinite sized, infinite dimension array of arbitrary sizes and contents.All the other recursion and loop based answers have a much lower upper limit to the size of the array structure they can create.And the creation speed will be a major issue for these larger structures.
Use this line instead to simulate pre-filling: var table = new Proxy({}, {get:(t,n)=>n in t ? t[n] : 42});
Nice, creative way to 'emulate' Array2D by object :)
5

I'm not a fan of the ES6 solutions using .fill(). Some may work but the extra hoops to avoid the copy-by-reference problems make them non-intuitive.

My suggested ES6 approach is to fully leverage the spread operator for both outer and inner arrays. It's easier to reason about IMO.

[...Array(3)].map(() => [...Array(4)]) 

If you need to set an initial value, then you chain on a .map() on the inner array creation:

[...Array(3)].map(() => [...Array(4)].map(() => 0)) 

Lastly, a type-safe TypeScript util function:

export const createMultiDimensionalArray = <T>( n: number, m: number, initialVal?: T, ): T[][] => { const matrix = [...Array(n)].map(() => [...Array(m)]); return initialVal === undefined ? matrix : matrix.map(r => r.map(() => initialVal)); }; 

Examples using it:

const a = createMultiDimensionalArray(1, 2); a[1][2] = 3; // Works const b = createMultiDimensionalArray(2, 3, false); b[1][2] = true; // Works b[1][2] = 3; // Error: Type '3' is not assignable to type 'boolean'. 

Comments

4

TL;DR To make a 2-dimensional array in JavaScript:

let grid = Array(NUMBER_ROWS).fill().map(_ => Array(NUMBER_COLUMNS).fill(0)); 

Creating a 2D array in Chrome DevTools JavaScript console Explanation:

  • This example portrays row-major order, indexed by row, then by column: grid[iRow][iColumn]
  • Array(NUMBER_ROWS) creates the barest of bones outer array. It has length but no elements. It is empty.
  • Array(NUMBER_ROWS).fill() creates an array of undefined elements. This is a not the same as an empty array.
  • .fill() expects a parameter. But in JavaScript omitting a parameter is well behaved: if it doesn't have a default value, it passes undefined. From MDN: "In JavaScript, function parameters default to undefined."
  • We don't care what the outer array is initially filled with. But if we didn't fill it with something, then .map() would not convert any of the somethings -- the arrow function would never get called back.
  • The arrow function in .map() translates each undefined element from the outer array into an inner array.
  • The arrow function in .map() gets passed an argument but we ignore it. Here it is represented by _.
  • This code actually throws away the outer array filled with undefined. What's ultimately stored in grid is the output of .map(), a new outer array that contains the inner arrays.
  • Array(NUMBER_COLUMNS) creates an inner array, a row.
  • .fill(0) fills it with zeroes.
  • The Array() constructor does not need the new operator.
  • I based this on the "inefficient alternative" in the thorough answer by @zurfyx. Thanks @JinsongLi for the idea of omitting the parameter to .fill(). I like the suggestion by @TJCrowder of _ for unused parameters.
  • CAUTION: Never pass an array to Array.fill(). That leads to clones and madness. Here, each iteration of .map() calls the arrow function and creates a shiny new and distinct inner array.

This method expands well to higher dimensions. Here is a 3-dimensional array: 3D array in JavaScript

Comments

3

You could allocate an array of rows, where each row is an array of the same length. Or you could allocate a one-dimensional array with rows*columns elements and define methods to map row/column coordinates to element indices.

Whichever implementation you pick, if you wrap it in an object you can define the accessor methods in a prototype to make the API easy to use.

Comments

3

I found that this code works for me:

var map = [ [] ]; mapWidth = 50; mapHeight = 50; fillEmptyMap(map, mapWidth, mapHeight); 

...

function fillEmptyMap(array, width, height) { for (var x = 0; x < width; x++) { array[x] = []; for (var y = 0; y < height; y++) { array[x][y] = [0]; } } } 

Comments

3

A simplified example:

var blocks = []; blocks[0] = []; blocks[0][0] = 7; 

Comments

2

I've made a modification of Matthew Crumley's answer for creating a multidimensional array function. I've added the dimensions of the array to be passed as array variable and there will be another variable - value, which will be used to set the values of the elements of the last arrays in the multidimensional array.

/* * Function to create an n-dimensional array * * @param array dimensions * @param any type value * * @return array array */ function createArray(dimensions, value) { // Create new array var array = new Array(dimensions[0] || 0); var i = dimensions[0]; // If dimensions array's length is bigger than 1 // we start creating arrays in the array elements with recursions // to achieve multidimensional array if (dimensions.length > 1) { // Remove the first value from the array var args = Array.prototype.slice.call(dimensions, 1); // For each index in the created array create a new array with recursion while(i--) { array[dimensions[0]-1 - i] = createArray(args, value); } // If there is only one element left in the dimensions array // assign value to each of the new array's elements if value is set as param } else { if (typeof value !== 'undefined') { while(i--) { array[dimensions[0]-1 - i] = value; } } } return array; } createArray([]); // [] or new Array() createArray([2], 'empty'); // ['empty', 'empty'] createArray([3, 2], 0); // [[0, 0], // [0, 0], // [0, 0]] 

Comments

2

Recursive function to create a multi-dimensional array:

var makeArray = function (dims, arr) { if (dims[1] === undefined) { return new Array(dims[0]); } arr = new Array(dims[0]); for (var i=0; i<dims[0]; i++) { arr[i] = new Array(dims[1]); arr[i] = makeArray(dims.slice(1), arr[i]); } return arr; } 

Build a 2x3x4x2 4D-Array:

var array = makeArray([2, 3, 4, 2]); 

Comments

2
 var items = [ ["January 01", 42.5], ["February 01", 44.3], ["March 01", 28.7], ["April 01", 44.3], ["May 01", 22.9], ["June 01", 54.4], ["July 01", 69.3], ["August 01", 19.1], ["September 01", 82.5], ["October 01", 53.2], ["November 01", 75.9], ["December 01", 58.7] ]; alert(items[1][0]); // February 01 alert(items[5][1]); // 54.4 

Comments

2
const arr = new Array(5).fill(new Array(5).fill(0)); console.log(arr); 

3 Comments

Since this is answer is the shown as the first result I just want to mention that (like others already mentioned) in this solution the second dimension arrays are copied by reference so this may not be the best way to create a 2D array
@air5 You seem to be unaware that sorting order is not predicatable. There is no such think as "first" here. The order is individually configurable.
This actually messed me up at first. Since it is filling the 2nd dimension with the first array by reference, any change made to any array will affect all arrays in the the 2nd dimension.
2

use the global object Array and fill items with arrays:

let arr = new Array(5).fill([]); 

or if the 2d array of known length:

let arr = new Array(5).fill(new Array(2)); 

1 Comment

2nd one in the or is not correct! Because it creates a shallow copy of Array(2) at each index of the first array. So if you set arr[0][0] = 1 then it will modify the arr[1][0], arr[2][0], arr[3][0] and so on ..... to 1 also.
1

You can also create a function to create a 2D array like this:

var myTable = []; function createArray(myLength) { myTable = new Array(myLength); var cols, rows; for (cols = 0; cols < myLength; cols++) { myTable[cols] = new Array(myLength); } } 

You can call it by using the following, which will give you a 10x10 2D array.

createArray(10); 

You also can create a 3D array using this method.

Comments

1

nodejs + lodash version:

var _ = require("lodash"); var result = _.chunk(['a', 'b', 'c', 'd', 'e', 'f'], 2); console.log(result); console.log(result[2][0]); 

The output:

[ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e', 'f' ] ] e 

Comments

1

If all you want is a 4x4 matrix have a look at DOMMatrix, it is easy to use I can say,

let m = new DOMMatrix(); // m.m11, m.m12, m.m13, m.m14, ..., m.m41, m.m42, m.m43, m.m44 

Initially brought for different reasons, it is not available on node.js and only limited to 4x4.

Also you can consider using an auto-vivification object instead arrays for JS, have a look at my answer here but brought here also for more convince:

var tree = () => new Proxy({}, { get: (target, name) => name in target ? target[name] : target[name] = tree() }); var t = tree(); t[0][2][3] = 4; console.log(t[0][2][3]); 

It uses new JS and acts not correctly when you iterate through it so be careful with it.

Also have a look at this if you need a flexible multi-dimension array generator.

Comments

1
Array.from({length: rows}).map(e => new Array(columns)); 

Comments

1

My solution won't be the best one, But just giving my solutions to create user-defined multidimensional array.

This function accepting rows and columns,

function createArray(row,column) { let arr = []; for(var i=0; i<row; i++){ arr[i] = [Math.floor(Math.random() * (10))]; for(var j=0;j<column;j++){ arr[i][j]= [Math.floor(Math.random() * (20))]; } } return arr; } var arrVal = createArray(4, 5); console.log(arrVal); 

2 Comments

Please do not pile a question on what is otherwise an answer.
Sure, Yuuosch. will not
1

This constructs arrays of any dimension.

function makeArrayChildren(parent, firstDimension, ...dimensions) { for (let i = 0; i < parent.length; i++) { parent[i] = new Array(firstDimension); if (dimensions.length != 0) { makeArrayChildren(parent[i], ...dimensions); } } } function makeArray(firstDimension, ...dimensions) { if (firstDimension == undefined) { throw Exception("Too few dimensions"); } let topArray = new Array(firstDimension); if (dimensions.length != 0) makeArrayChildren(topArray, ...dimensions); return topArray; } 

Here's another two functions I wanted to make, which I can use as a sanity check: a for each that executes on all the lowest level items in a multi dimensional array and a fill method.

Array.prototype.dimensionalFill = function (value) { for (let i = 0; i < this.length; i++) { const elem = this[i]; if (elem instanceof Array) { elem.dimensionalFill(value); } else { this[i] = value; } } }; /*Unlike forEach, this also loops over undefined values. */ Array.prototype.dimensionalForEach = function (callableFunc, thisArg) { if (thisArg != undefined) { return this.dimensionalForEach(callableFunc.bind(thisArg)); } for (let i = 0; i < this.length; i++) { const elem = this[i]; if (elem instanceof Array) { elem.dimensionalForEach(callableFunc); } else { callableFunc(elem, i, this); } } }; 

And here's a nice little sanity check that uses all the features. So at the very least, it can't be completely wrong.

let arr = makeArray(10, 10, 5, 4); arr.dimensionalFill(2); let sum = 0; arr.dimensionalForEach((elem) => { sum += elem; }); console.log(`sum: ${sum} === ${10 * 10 * 5 * 4 * 2}`); 

It bears mentioning that at this point, it would've been a far better practice to create an altogether new structure, but this was fun.

Comments

0

If you are after 2D array for google charts, the best way to do it is

var finalData = []; [["key",value], ["2013-8-5", 13.5], ["2013-7-29",19.7]...] 

referring to Not a valid 2d array google chart

Comments

0
var _field = (function() { var array = []; for(var y = 0; y != 3; y++) { array[y] = new Array(5); } return array; })(); // var item = _field[2][4]; 

Comments

0

What happens if the size of array is unknown? Or array should be dynamically created and populated? Alternative solution which worked for me is to use class with static 2d array variable which in case of non-existence of index in array will initiate it:

function _a(x,y,val){ // return depending on parameters switch(arguments.length){ case 0: return _a.a; case 1: return _a.a[x]; case 2: return _a.a[x][y]; } // declare array if wasn't declared yet if(typeof _a.a[x] == 'undefined') _a.a[x] = []; _a.a[x][y] = val; } // declare static empty variable _a.a = []; 

The syntax will be:

_a(1,1,2); // populates [1][1] with value 2 _a(1,1); // 2 or alternative syntax _a.a[1][1] _a(1); // [undefined × 1, 2] _a.a; // [undefined × 1, Array[2]] _a.a.length 

Comments

0

An awesome repository here .

  • api : masfufa.js

  • sample : masfufa.html

Two Examples will be enough to understand this library :

Example 1:

 /* | 1 , 2 , 3 | * MX= | 4 , 5 , 6 | Dimensions= 3 x 3 * | 7 , 8 , 9 | */ jsdk.getAPI('my'); var A=[1, 2, 3, 4, 5, 6, 7, 8, 9]; var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'}); 

then :

MX.get[0][0] // -> 1 (first) MX.get[2][2] // ->9 (last) 

Example 2:

 /* | 1 , 9 , 3 , 4 | * MXB= | 4 , 5 , 6 , 2 | Dimensions= 2 x 4 * */ var B=[1 , 9 , 3 , 4 , 4 , 5 , 6 , 2]; var MXB=myAPI.getInstance('masfufa',{data:B,dim:'2x4'}); 

then :

MXB.get[0][0] // -> 1 (first) MXB.get[1][3] // -> 2 (last) MXB.get[1][2] // -> 6 (before last) 

Comments

0

This is mentioned in a few of the comments, but using Array.fill() will help construct a 2-d array:

function create2dArr(x,y) { var arr = []; for(var i = 0; i < y; i++) { arr.push(Array(x).fill(0)); } return arr; } 

this will result in an array of length x, y times in the returned array.

Comments

0

This is my implementation of Multi-Dimension Array.

In this approach, I am creating a single dimension array

I have added a prototype function multi to Array object, Which can be used to create any dimension Array.

I have also added a prototype function index to Array object, Which can be used to get index in linear Array from multi-dimension indexes.

Creating a Array

//Equivalent to arr[I][J][K]..[] in C var arr = new Array().multi(I,J,K,..); 

Accessing array value at any index

//Equivalent in C arr[i][j][k]; var vaue = arr[arr.index(i,j,k)]; 

SNIPPET

/* Storing array as single dimension and access using Array.index(i,j,k,...) */ Array.prototype.multi = function(){ this.multi_size = arguments; this.multi_len = 1 for(key in arguments) this.multi_len *= arguments[key]; for(var i=0;i<this.multi_len;i++) this.push(0); return this; } Array.prototype.index = function(){ var _size = this.multi_len; var temp = 1; var index = 0; for(key in arguments) { temp*=this.multi_size[key]; index+=(arguments[key]*(_size/temp)) } return index; } // Now you can use the multi dimension array // A 3x3 2D Matrix var arr2d = new Array().multi(3,3); // A 2D Array arr2d[arr2d.index(1,1,1)] = 5; console.log(arr2d[arr2d.index(1,1,1)]); // A 3x3x3 3D Matrix var arr3d = new Array().multi(3,3,3); // a 3D Array arr3d[arr3d.index(1,1,1)] = 5; console.log(arr3d[arr3d.index(1,1,1)]); // A 4x3x3 4D Matrix var arr4d = new Array().multi(4,3,3,3); // a 4D Array arr4d[arr4d.index(4,0,0,1)] = 5; console.log(arr4d[arr4d.index(4,0,0,1)]);

Comments

0

Creates n dimensional matrix array for Java Script, filling with initial default of value 0.

function arr (arg, def = 0){ if (arg.length > 2){ return Array(arg[0]).fill().map(()=>arr(arg.slice(1))); } else { return Array(arg[0]).fill().map(()=>Array(arg[1]).fill(def)); } } // Simple Usage of 4 dimensions var s = arr([3,8,4,6]) // Use null default value with 2 dimensions var k = arr([5,6] , null) 

Comments

1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.