Multidimensional arrays in javaScript

In JavaScript Multidimensional arrays can be implemented in a number of ways. Maybe the most common way is to just have arrays of arrays, however there are other ways of doing so that involve just having a single linear array and a formula to get or set the proper index value in the javaScript array. In addition there is also doing things like having an array of arrays, bit each element is an object and these objects then have an array as one of its properties.

Multidimensional arrays will come up often when it comes to any kind of project that will involve a 2d grid, a 3d plane, tables, or anything else where doing so might be called for when doing something interesting with many dimensions. So having a solid understanding of the different ways to go about having arrays with two or more dimensions is called for when it comes to a wide range of applications where the use of them will come into play. So lets look at some typical examples, as well as some other examples that might be not so typical with multidimensional arrays in javaScript.

1 - Using Arrays of arrays

The most common way of making a multidimensional array in javaScript might be to just have arrays of arrays. That is having a single array, and then have each element in that array be an array. That alone would be a 2d array of arrays at which point making each element in each nested array an array would add yet another dimension, and so on.

In this section I will be going over just some simple examples of making 2d arrays of arrays this way.

1.1 - Using literal array bracket syntax to create a static array of arrays

So for this example I just have a grid of single digit hex values that is four by four. I start out with just a simple array, and then have four arrays within that array. In each nested array I then have my hex values where the lowest hex value is the first index of the first nested array, things then progress from that index value forward to the end of the nested array, and then continue in the next.

I can then access the primitive value in each nested array, by using the bracket syntax just like a single array, only when doing so I get a nested array rather than a primitive value, so Then need to give the index value of the element that I want in the nested array to get an element with one of my hex values.

If you are still confused maybe it would be best to look at a code example of this.

1
2
3
4
5
6
7
8
9
10
11
12
13
// a 2d array of arrays can be created
// in a literal way like this
var grid = [
['0', '1', '2', '3'],
['4', '5', '6', '7'],
['8', '9', 'a', 'b'],
['c', 'd', 'e', 'f']
];
// elements can then be accessed like this
var cell = grid[3][2];
console.log(cell); // 'e'

This is a static form of a 2d array of arrays, however often I will want to have a way to generate such an array, so for this I will want to use some loops, and maybe do so in the body of a function.

1.2 - Using a function that will generate an array of arrays

I almost all projects I will want a way to go about creating a multidimensional array by way of some javaScript code that will generate the state of the array rather than the state being some kind of fixed hard coded value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// A function of some kind like this can be used
// to create the gird
var createGrid = function (w, h, forCell) {
var grid = [],
y = 0,
row,
i = 0,
x;
w = w === undefined ? 3 : w;
h = h === undefined ? 3 : h;
forCell = forCell === undefined ? function (i) {
return i;
}
: forCell;
while (y < w) {
x = 0;
row = [];
while (x < h) {
row.push(forCell(i));
i += 1;
x += 1;
}
grid.push(row);
y += 1;
}
return grid;
};
// I can then create the same grid like this
var grid = createGrid(4, 4, function (i) {
return i.toString(16);
});
var cell = grid[3][2];
console.log(cell); // 'e'

2 - Using just one linear array

Although arrays of arrays work okay, I often just use a single array, and then work out a formula that is used to figure the proper index value for this single array.

2.1 - A static example of using a single array and formula to get the proper index value

One again lets start out with a simple static hard coded form of this kind of multinational array in javaScript.

1
2
3
4
5
6
7
8
9
10
var grid = {
w: 4,
h: 4,
cells: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'],
get: function (x, y) {
return this.cells[y * this.w + x];
}
};
console.log(grid.get(2, 3)); // 'e'

2.2 - Making a function that will return an API with a single array and get method

Now to do the same thing, only once again make a function that will return my multidimensional array. Only this time it will return the array along with at least a width property. In addition I might also want a height property, and a method that I can use to get a location by way of passing an x and y value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var createGrid = function (w, h, forCell) {
w = w === undefined ? 3 : w;
h = h === undefined ? 3 : h;
forCell = forCell === undefined ? function (i) {
return i;
}
: forCell;
var cells = [],
i = 0,
len = w * h;
while (i < len) {
cells.push(forCell(i));
i += 1;
}
return {
w: w,
h: h,
cells: cells,
get: function (x, y) {
return this.cells[y * this.w + x];
}
};
};
var grid = createGrid(4, 4, function (i) {
return i.toString(16);
});
console.log(grid.get(2, 3)); // 'e'

3 - Three or more dimensions

So then there is working something out for working with three or more dimensions. I quickly put something together for that, but it is still not working the way I would like it to really.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
var lengthFromDims = function (dims) {
return Object.values(dims).reduce(function (acc, n) {
return acc * n;
});
};
// get Dim Value by index
var getDVByIndex = function (dims, i) {
return Object.values(dims)[i];
};
// get the product of all dims from si to ei
var getDimProduct = function (dims, si, ei) {
var p = getDVByIndex(dims, si),
i = si + 1;
while (i <= ei) {
p = p * getDVByIndex(dims, i);
i += 1;
}
return p;
};
var threePlus = function (dims, forCell) {
dims = dims || {
x: 2,
y: 2,
z: 2
};
var threePlus = [],
i = 0,
len = lengthFromDims(dims),
pos = {};
while (i < len) {
Object.keys(dims).forEach(function (dimName, di) {
var val = dims[dimName];
// product of all dims from 0 to current
var p = getDimProduct(dims, 0, di);
// product of dims from less one from current to current
var pdi = di - 1 < 0 ? 0 : di - 1;
var p2 = getDimProduct(dims, pdi, di);
var p3 = getDimProduct(dims, pdi, di - 1);
//var s1 = (i % p2 + Math.floor(i / p)) % val;
var a = i % p2,
b = Math.floor(i / p),
c = a + b,
s1 = c % val;
pos[dimName] = s1;
});
var cell = {};
cell.i = i;
Object.keys(pos).forEach(function (d) {
cell[d] = pos[d];
});
threePlus.push(cell);
i += 1;
}
return threePlus;
};
var print = function (threePlus) {
return threePlus.map(function (a) {
var vals = Object.values(a);
return a.i + ':' + vals.slice(1, vals.length).join('');
}).sort().join('\n');
}
var three = threePlus({
x: 2,
y: 2,
z: 2
});
console.log(print(three));
// output
// 0:000
// 1:111
// 2:100
// 3:011
// 4:010
// 5:101
// 6:110
// 7:001
// Desired output
// 0:000 0
// 1:100 2
// 2:010 4
// 3:110 6
// 4:001 7
// 5:101 5
// 6:011 3
// 7:111 1