Reputation: 145
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
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
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
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