3

Anyone have a function to create 4D arrays (or any number of dimensions for that matter)?

I'd like to call the function, then after that I can do something like arr[3][2][23][12] = "awesome";

trusktr
  • 44,284
  • 53
  • 191
  • 263
  • possible duplicate of [Is there a more concise way to initialize empty multidimensional arrays?](http://stackoverflow.com/questions/17776149/is-there-a-more-concise-way-to-initialize-empty-multidimensional-arrays) – Anderson Green Jul 21 '13 at 21:18

8 Answers8

8
function make(dim, lvl, arr) {
  if (lvl === 1) return [];
  if (!lvl) lvl = dim;
  if (!arr) arr = [];
  for (var i = 0, l = dim; i < l; i += 1) {
    arr[i] = make(dim, lvl - 1, arr[i]);
  }
  return arr;
}

var myMultiArray = make(4);

Update: you can specify how deep a level should be in the first parameter, and how many levels in the second. e.g.:

var myMultiArray = make(64, 4);

This will allow you to set and get in this format:

myMultiArray[X][X][X][X] = ....

But X must always be less than 64. You cannot set myMultiArray[X][70][X][X] for example, because myMultiArray[X][70] has not yet been defined

Note- running make(64, 4) is awfully slow - you are creating 64 ^ 4 empty array elements (i.e. 16,777,216).

Update 2: you can get away with the last value as any number or string. Ie. myMultiArray[X][X][X][Y] where X < 64 and Y can be anything.

The algorithm has been optimised as well, give it another go.

Matty F
  • 3,763
  • 4
  • 30
  • 48
  • I tried it, but it didn't work as expected. I did this: `var adjMatrix = makeArray(4); adjMatrix[6][2][4][5] = 'foobar'; alert(adjMatrix[6][2][4][5]);` But the alert didn't work. – trusktr May 19 '11 at 02:37
  • 1
    you can't assign adjMatrix[6][2] if adjMatrix[6] doesn't yet exist, it sounds like you need a function to specify how deep you'd like each dimension. will update this with one – Matty F May 19 '11 at 02:40
  • Wow, that's awesome! Although it could potentially be bad for memory usage if used carelessly, it does exactly what I was looking for! Two thumbs way up! – trusktr May 19 '11 at 03:00
  • 1
    just updated with optimisations that should make a major improvement – Matty F May 19 '11 at 03:05
5

Quick and dirty:

var arr = [[[[[]]]]];

Check it out http://jsfiddle.net/MJg9Y/

Note: You will still need to initialize each dimension. The above creates the foundation for a 4 dimension array at arr[0].

Jason McCreary
  • 71,546
  • 23
  • 135
  • 174
  • I tried doing this: `arr[0][1][0][3] = 'test'; alert(arr[0][1][0][3]);` But that didn't work. How would you set that for example? – trusktr May 19 '11 at 02:42
  • an you do that after the array is already created like in your example? – trusktr May 19 '11 at 02:54
  • 1
    Yeah, so `arr[1] = [[[]]]`. You'll need to do this all the way down the line though. So a recursive function might be less tedious. I was merely providing the *quick and dirty* way to init an array. – Jason McCreary May 19 '11 at 02:56
  • 1
    @trusktr just for fun : `arr = [[[],[[[],[],[],['test']]]]]; alert(arr[0][1][0][3]);` works ! ;-) – Apolo May 15 '14 at 14:20
3

Here's a simple recursive solution. The real brains is the mdim function. It just calls itself if the depth isn't 1, and when it gets there just returns an empty array.

Since it seems like you might want to use this for a lot of things, I've wrapped it in a prototype off of Array so that you can use it on your arrays automatically (convenience/maintainability tradeoff). If you prefer, grab the mdim function out of the closure and it should work just fine.

There's a simple test case at the end so you can see how to use it. Good luck! :)

//adds a multidimensional array of specified depth to a given array
//I prototyped it off of array for convenience, but you could take 
//just the mdim function
Array.prototype.pushDeepArr = function( depth ){
    var arr = (mdim = function( depth ){
        if( depth-- > 1 ){
            return [ mdim( depth ) ];
        } else {
            return [];
        }
    })(depth);
    this.push(arr);
};

//example: create an array, add two multidimensional arrays
//one of depth 1 and one of depth 5
x = [];
x.pushDeepArr(1);
x.pushDeepArr(5);
cm2
  • 12,349
  • 1
  • 17
  • 11
  • Wow, that seems amazing. So after you `.pushDeepArr(1)` and `.pushDeepArr(5)` on `x`, what does that leave you with exactly? For example, i'd want the first two dimensions to be size 3 and the last two to be size 6, how would I use .pushDeepArr() to build x so the last item would therefore be x[2][2][5][5]? – trusktr May 19 '11 at 03:18
  • In this case x would be `[ [], [[[[[]]]]] ]`. This function just builds the depth. To get the correct length for each level, I suppose it would need a parameter to hold the width of each level. – cm2 May 19 '11 at 03:42
2

Just set each value in an existing array equal to a new array, with however many elements you need.

See this tutorial for some good examples. You can do this with any number of dimensions.

var myArray = new Array(3);

for (var i = 0; i < 3; i++) {
    myArray[i] = new Array(3);
    for (var j = 0; j < 3; j++) {
        myArray[i][j] = '';
    }
}
Cyclone
  • 17,939
  • 45
  • 124
  • 193
  • This looks cool... If there was a recursive-function version of this, where you'd end up with 4 for loops if you want 4 arrays, that'd be awesome! The call could be like this: `makeArray(2,4,3,6);` where each int would be the size of each dimension. – trusktr May 19 '11 at 02:45
1

Fwiw, I posted an object with a three dimensional array here. In that example,

objTeams.aaastrTeamsByLeagueCityYear["NFL"]["Detroit"][2012] == "Lions".
Community
  • 1
  • 1
1

Very simple function, generate an array with any number of dimensions. Specify length of each dimension and the content which for me is '' usually

function arrayGen(content,dims,dim1Len,dim2Len,dim3Len...) {
  var args = arguments;
  function loop(array,dim) {
    for (var a = 0; a < args[dim + 1]; a++) {
      if (dims > dim) {
        array[a] = loop([],dim + 1);
      } else if (dims == dim) {
        array[a] = content;
      }
    }
    return array;
  }
  var thisArray = [];
  thisArray = loop(thisArray,1);
  return thisArray;
};

I use this function very often, it saves a lot of time

Indiana Kernick
  • 5,041
  • 2
  • 20
  • 50
1

Use the following function to create and initialize Array of any dimension

function ArrayND(initVal) 
{
    var args = arguments;
    var dims=arguments.length-1
    function ArrayCreate(cArr,dim)
    {
        if(dim<dims)
        {
            for(var i=0;i<args[1 + dim];i++)
            {
                if(dim==dims-1) cArr[i]=initVal
                else    cArr[i]=ArrayCreate([],dim+1)
            }
            return cArr
        }
    }
    return ArrayCreate([],0)
}

For e.g to create an array of 2 rows and 3 columns use it like the following

var a=ArrayND("Hello",2,3)

This will create the require array and initialize all values with "Hello"

Similarly to create 4 dimensional array use it like

var a=ArrayND("Hello",2,3,4,5)
Arup Hore
  • 1,509
  • 15
  • 9
1

Update Corrected some issues with the previous function; this seems to do the trick:

function multidimensionalArray(){
    var args = Array.prototype.slice.call(arguments);

    function helper(arr){
        if(arr.length <=0){
            return;
        }
        else if(arr.length == 1){
            return new Array(arr[0]);
        }

        var currArray = new Array(arr[0]);
        var newArgs = arr.slice(1, arr.length);
        for(var i = 0; i < currArray.length; i++){
            currArray[i] = helper(newArgs);
        }
        return currArray;
    }

    return helper(args);
}

Usage

var a = multidimensionalArray(2,3,4,5);

console.log(a); //prints the multidimensional array
console.log(a.length); //prints 2
console.log(a[0].length); //prints 3
console.log(a[0][0].length); //prints 4
console.log(a[0][0][0].length); //prints 5
no.good.at.coding
  • 20,221
  • 2
  • 60
  • 51