如何在Javascript中重塑一个扁平数组到任意形状的多维数组?



[what I have]

有n个元素的扁平或一维数组,例如下面有12个元素的数组A。

const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 

[what i want do]

将A重塑为一个多维数组B,其形状是由数组C决定的,它可能会根据其他条件而变化。

// 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 try]

我找到了下面的参考,可以通过任意行数将一个扁平数组还原为二维数组:将数组还原为四组[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 figure out]

我还没有弄清楚如何制作一个"动态嵌套的for循环",或者需要某种递归,将一维数组重塑为由另一个数组确定的任意形状的多维数组。

感谢您的帮助。

我的解决方案是:


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是递归函数。由于封闭,它可以访问elemIndexarrdimelemIndex是指从数组arr中读取的当前元素的索引。

_nest取当前维数dimIndex的索引。

  • 如果dimIndex指向dim数组的最后一个维数,则必须返回相应大小的1D数组。这是递归的基本条件。它返回一个从elemIndex开始的arr切片,大小为dim[dimIndex]
  • 否则调用下一个维度_nest,dim[dimIndex]次。例如,当dimIndex为0时,即size为3 =>我们需要3个数组,因此我们调用_nest三次,每个数组的大小在上面的例子中是4。

递归是函数式的遗产,因此将它与函数式风格结合使用可以获得最佳效果。这意味着要避免突变、变量重赋和其他副作用。

另外,您的输入被过度指定。最后一个数字不需要,因为没有它也可以确定输出-

function nest (t, q) {
if (q.length < 1)
return t
else
return cut(t, t.length/q[0]).map(r => nest(r, q.slice(1)))
}
function cut (t, n) {
if (n >= t.length)
return [t]
else
return [t.slice(0,n), ...cut(t.slice(n), n)]
}
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
console.log(JSON.stringify(nest(A, [3])))
console.log(JSON.stringify(nest(A, [2,3])))

[[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
[[[1,2],
[3,4],
[5,6]],
[[7,8],
[9,10],
[11,12]]]

⚠️当q的输入不是t.length的因素时,预计会有意外的输出

最新更新