14

I've been trying to find a reasonably concise way to set the dimensions of an empty multidimensional JavaScript array, but with no success so far.

First, I tried to initialize an empty 10x10x10 array using var theArray = new Array(10, 10 10), but instead, it only created a 1-dimensional array with 3 elements.

I've figured out how to initialize an empty 10x10x10 array using nested for-loops, but it's extremely tedious to write the array initializer this way. Initializing multidimensional arrays using nested for-loops can be quite tedious: is there a more concise way to set the dimensions of empty multidimensional arrays in JavaScript (with arbitrarily many dimensions)?

//Initializing an empty 10x10x10 array:
var theArray = new Array();
for(var a = 0; a < 10; a++){
    theArray[a] = new Array();
    for(var b = 0; b < 10; b++){
        theArray[a][b] = new Array();
        for(var c = 0; c < 10; c++){
            theArray[a][b][c] = 10
        }
    }
}

console.log(JSON.stringify(theArray));
7
  • The Java programming language has int[][] stuff = new int[10][10], but I'm not aware of any similar construct in JavaScript. Commented Jul 21, 2013 at 19:43
  • possible duplicate of How can I create a two dimensional array in JavaScript? Commented Jul 21, 2013 at 19:51
  • 2
    @Lion No, this question is asking how to initialize arrays of arbitrarily many dimensions, not just 2 dimensions. Commented Jul 21, 2013 at 19:54
  • 1
    @AndersonGreen Right, I missed the "arbitrary many dimensions" part. If you just need one 3dimensional array, a generic function may be overkill Commented Jul 21, 2013 at 20:16
  • 2
    +1 for an actually good question with a fun coding challenge! Commented Jul 21, 2013 at 20:39

6 Answers 6

6

Adapted from this answer:

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[i] = createArray.apply(this, args);
  }        
  return arr;
 }

Simply call with an argument for the length of each dimension. Usage examples:

  • var multiArray = createArray(10,10,10); Gives a 3-dimensional array of equal length.
  • var weirdArray = createArray(34,6,42,2); Gives a 4-dimensional array of unequal lengths.
Sign up to request clarification or add additional context in comments.

1 Comment

you can simplify your while using the one i did in my answer
3
function multiDimArrayInit(dimensions, leafValue) {
    if (!dimensions.length) {
        return leafValue;
    }
    var arr = [];
    var subDimensions = dimensions.slice(1);
    for (var i = 0; i < dimensions[0]; i++) {
        arr.push(multiDimArrayInit(subDimensions, leafValue));
    }
    return arr;
}


console.log(multiDimArrayInit([2,8], "hi")); // counting the nested "hi"'s yields 16 of them

demo http://jsfiddle.net/WPrs3/

1 Comment

Good job, two minor nitpicks: callee is deprecated and it's better to move slice out of the loop.
1

Here is my take on the problem: nArray utility function

function nArray() {
    var arr = new Array();
    var args = Array.prototype.slice.call(arguments, 1);
    for(var i=0;i<arguments[0];i++) {
        arr[i] = (arguments.length > 1 && nArray.apply(this, args)) || undefined;
    }
    return arr;
}

Usage example:

var arr = nArray(3, 3, 3);

Results in 3x3x3 array of undefined values.

Running code with some tests also available as a Fiddle here: http://jsfiddle.net/EqT3r/7/

Comments

0

The more dimension you have, the more you have interest in using one single flat array and a getter /setter function for your array.
Because for a [d1 X d2 X d3 X .. X dn] you'll be creating d2*d3*...*dn arrays instead of one, and when accessing, you'll make n indirection instead of 1.

The interface would look like :

var myNArray = new NArray(10,20,10);
var oneValue = myNArray.get(5,8,3);
myNArray.set(8,3,2, 'the  value of (8,3,2)');

the implementation depends on your preference for a fixed-size n-dimensionnal array or an array able to push/pop and the like.

Comments

0

A more succinct version of @chris code:

function multiDim (dims, leaf) {
  dims = Array.isArray (dims) ? dims.slice () : [dims];
  return Array.apply (null, Array (dims.shift ())).map (function (v, i) {
    return dims.length 
      ? multiDim (dims, typeof leaf == 'string' ? leaf.replace ('%i', i + ' %i') : leaf)
      : typeof leaf == 'string' ? leaf.replace ('%i', i) : leaf;
  });      
}

console.log (JSON.stringify (multiDim ([2,2], "hi %i"), null, '  ')); 

Produces :

[
  [
    "hi 0 0",
    "hi 0 1"
  ],
  [
    "hi 1 0",
    "hi 1 1"
  ]
]

In this version you can pass the first argument as a number for single dimension array. Including %i in the leaf value will provide index values in the leaf values.

Play with it at : http://jsfiddle.net/jstoolsmith/r3eMR/

Comments

0

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(dim) {
    var array = [];
    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 = loop(1);
  return thisArray;
};

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.