Andrea
Andrea

Reputation: 13

Could not perform a recursive multidimensional array

I am making a recursive multidimensional array in javascript. But with a matrix I find it difficult.

For example, when I do this: matrix([2,3,4]) I want it to return this to me:

[ [ [ 0, 1, 2, 3 ] 
  , [ 0, 1, 2, 3 ] 
  , [ 0, 1, 2, 3 ] 
  ] 
, [ [ 0, 1, 2, 3 ] 
  , [ 0, 1, 2, 3 ] 
  , [ 0, 1, 2, 3 ] 
] ] 

The length of the entered matrix must be the number of dimensions and the numbers must be the value of the dimensions, having a 3D 2x3x4 matrix (height, width and height).

Code:

function copyArray(A)
{
  var B=[]
  for(var i=0;i<A.length;i++)
  {
      B[i]=A[i]
  }
  return B
}

function matrix(dims)
{
  var I=dims[0]
  dims.shift()
  var A=[]
  A.length=I
  for(var i=0;i<I;i++)
  {
     var dims2=copyArray(dims)
     A[i]=matriz(dims)
     dims=dims2
  }
  return A
}

The code I have generates the following error:

Uncaught RangeError: Invalid array length(…)

Upvotes: 0

Views: 63

Answers (3)

charlietfl
charlietfl

Reputation: 171679

Another approach using Array.from() and it's built in mapper

const matrix = (dims) => (
   Array.from({length: dims.shift()}, (_,i) => dims.length ? matrix([...dims]) : i)
)

console.log(matrix ([2,3,4]))

Upvotes: 0

Emy
Emy

Reputation: 62

You can do it this way, but it should be mentioned first:

  1. Array(length): to create an array of the specified length.
  2. .shift(): to remove the first element from the array.
  3. dims.length ?: to see if the recursive function should still be executed.
  4. dims.slice(0): to clone the array passed to the function.

function matrix(dims) {  
  var arr = Array(dims.shift() || 0);
  for(var idx = 0; idx < arr.length; idx++) {
    arr[idx] = dims.length ? matrix(dims.slice(0)) : idx;
  }
  return arr;
}

console.log( matrix([2,3,4]) )
.as-console-wrapper {max-height: 100%!important;top:0}

Upvotes: 1

Use a recursive function for this... build the level according to the dimension remove the index of the level you have dealt and move foward... do this until there no more dimensions to be handled.

This is an example of how to do it...

const createRange = (FROM, TO) => [...Array(TO - FROM + 1).keys()].map(i => i + FROM);

const createMatrix = (dimensions) => {
  const dim = dimensions[0];
  const newDimensions = dimensions.slice(1, dimensions.length);
  
  if (!newDimensions.length) return createRange(0, dim - 1);
  
  return [...Array(dim).keys()]
    .map(_ => createMatrix(newDimensions));
};

console.log(
  createMatrix([2,3,4])
)

Upvotes: 0

Related Questions