Jhon
Jhon

Reputation: 145

Javascript function to create multi-dimensional arrays

Haii

I want a function (pure javascript) (no jQuery) that creates multi-dimensional arrays.

I've made one that is completely hard-coded, and that limit the number of dimensions which I can dive deep.

function nestTriArray(first, second, third){
  const arr = new Array(first);
  for(let i=0; i<first; i++){
    arr[i] = new Array(second);
    for(let j=0; j<second; j++){
      arr[i][j] = new Array(third);
    }
  }
  return arr;
}

const test = nestTriArray(3,2,3);
console.log(test);

Outputs the CORRECT result:

//[[[undefined, undefined, undefined], [undefined, undefined, undefined]], [[undefined, undefined, undefined], [undefined, undefined, undefined]], [[undefined, undefined, undefined], [undefined, undefined, undefined]]]

I had another attempt to try and make it multi-dimensional in one function (rather than hard-coding a standalone function for fourth-dimension, fifth-dimension...) where I pass to the function an array, the length of the array is the number of dimensions, and each element represents the length of each sub-array. It uses a recursive function. And it outputs wrong.

That's the try:

function nestArray(conf_array/*first, second, third*/){
  conf_array = [1].concat(conf_array);
  const arr = [];

  let last_in_ref = arr;
  function re(index){
    last_in_ref[conf_array[index]] = new Array(conf_array[index+1]);
    for(let i=0; i<conf_array[index]; i++){
      last_in_ref[i] = new Array(conf_array[index+1]);
    }
    last_in_ref = last_in_ref[index];
    console.log(arr);
    index++;
    if(index < conf_array.length){re(index);}
  }

  re(0);

  return arr;
}

const test = nestArray([3,2,3]);
console.log(test);

Outputs WRONG:

//[[[undefined, undefined], [[undefined, undefined, undefined], [undefined, undefined, undefined], [[undefined], [undefined], [undefined], [undefined]]], [undefined, undefined], [undefined, undefined]], [undefined, undefined, undefined]]

Thanks in advance!!

Upvotes: 0

Views: 127

Answers (3)

shmulvad
shmulvad

Reputation: 638

Here is a recursive implementation that accomplishes what you want:

function nestArray(arrDims) {
    const [head, ...tail] = arrDims;
    const arr = new Array(head);
    return tail.length > 0 ? arr.fill(0).map(() => nestArray(tail)) : arr;
}

console.log(nestArray([5]));
console.log(nestArray([4, 3, 2]));

Upvotes: 1

user120242
user120242

Reputation: 15268

In the unlikely event you need these optimizations: Performance Tips
If you are trying to optimize by pre-initializing the arrays, read Avoid Creating Holes

reduceRight approach:

const nestedArray = (...args) => args.reduceRight((arr, length, i) =>
      Array.from({length}, _ => i ? arr : arr.map(x=>[...x])), Array(args.pop()))

let x
console.log(
    x=nestedArray(3,2,4)
)

x[0][0][0]=123

console.log(
    x
)

recursive approach:

const nestTriArray = (length, ...args) => {
  if(!args.length) return Array(length)
  return Array.from({length}, _=>[...nestTriArray(...args)])
}

const test = nestTriArray(3,2,1);
console.log(test);


test[0][0][0]=123
console.log(test);

Upvotes: 1

Dmytro Biletskyi
Dmytro Biletskyi

Reputation: 1903

Here is variant with reduce

[Edit] fixed with shallow copy and reduceRight from comments.

const nestArray = arr =>
  arr.reduceRight((acc, v) => {
    return new Array(v).fill(null).map(()=> acc ? [...acc] : acc);
  }, undefined);

console.log(nestArray([2, 5, 7, 10]));

Upvotes: 0

Related Questions