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.

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.