[what I have]
An flattened, or 1-dimentional, array with n elements, e.g. the array A with 12 items below.
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[what i want to do]
Reshape A to a multidimensional array B whose shape is determined by array C which may vary depending on other conditions.
// scenario 1
const C = [ 2, 3, 2 ]
// reshaped A should be:
// [[[1, 2],
// [3, 4],
// [5, 6]],
// [[7, 8],
// [9, 10],
// [11, 12]]]
// scenario 2
const C = [ 3, 4 ]
// reshaped A should be:
// [[1, 2, 3, 4],
// [5, 6, 7, 8],
// [9, 10, 11, 12]]
// and so on...
[what I have tried]
I found the follolwing reference which can unflattend a flattened array to a 2-dimensional array by arbitray number of rows: Unflatten Arrays into groups of fours [closed]
function arrayUnflatten (_flattenedArray, _numRows) {
const len = _flattenedArray.length;
const unflattenedArray = [];
while (_flattenedArray.length > 0) unflattenedArray.push(_flattenedArray.splice(0, _numRows));
return unflattenedArray;
}
[what I haven't figured out]
I haven't figured out how to make a "dynamically nested for loop", or some kind of recursion is needed, to reshape the 1-D array to a multidimensional arry in arbitrary shape determied by another array.
Help is appreciated.
Here's my solution:
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
const C = [3, 4];
function unflattenArray(arr, dim) {
let elemIndex = 0;
if (!dim || !arr) return [];
function _nest(dimIndex) {
let result = [];
if (dimIndex === dim.length - 1) {
result = result.concat(arr.slice(elemIndex, elemIndex + dim[dimIndex]));
elemIndex += dim[dimIndex];
} else {
for (let i = 0; i < dim[dimIndex]; i++) {
result.push(_nest(dimIndex + 1));
}
}
return result;
}
return _nest(0);
}
console.log(unflattenArray(A, C));
_nest
is a recursive function. Because of closure it can access elemIndex
, arr
and dim
. elemIndex
refers to the index of the current element being read from array arr
.
_nest
takes the index of the current dimension: dimIndex
. It's first called with 0.
dimIndex
refers to the last dimension in dim
array, then a 1D array of the corresponding size has to be returned. This is the base condition of recursion. It returns a slice of arr
starting at elemIndex
, of size dim[dimIndex]
._nest
with the next dimension, dim[dimIndex]
times. For e.g when dimIndex is 0 i.e size is 3 => we need 3 arrays hence we call _nest
thrice with the size of each array which is 4 in the above example.