0

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!!

2
  • Hey guys thanks alot really appreciate all the answers!! Commented Jun 8, 2020 at 0:05
  • So to sum it up, there’s lots of ways to do it (Thankss!!). But outside of conciseness, which one will execute the fastest??? Commented Jun 8, 2020 at 0:46

3 Answers 3

1

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);

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for the 2 approaches !! which one will perform faster?
In a micro-benchmark with very large arrays, for loop using only push and Array() constructor will probably be the fastest. recursion approach of the above next. fill-map will probably be better than Array.from. In reality the difference is most of the time negligible and probably won't matter.
recursion without tail recursion runs the risk of a stack overflow if the amount of nesting is excessive
1

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]));

1 Comment

Thans a lot. Plus it's so concise. Just perfect.
0

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]));

4 Comments

This is not correct. You need to shallow clone [...acc] to avoid reusing the same reference.
It's telling me it contains a "circular object array" which I don't know what it is.
@user120242 you are right, tried to make it too concise.
FYI: you can use reduceRight instead of reverse. Also, it's still pointing to the same reference on each iteration, just this time they're pointing to a clone.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.