如何在 Javascript 中将展平数组重塑为任意形状的多维数组?
How to reshape a flattened array to a multidimensional array in arbitray shape in Javascript?
[我有什么]
具有 n 个元素的扁平化或一维数组,例如数组 A 下面有 12 个项目。
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[我想做什么]
将 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...
[我试过的]
我找到了以下参考资料,它可以按任意行数将展平数组展开为二维数组: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;
}
[我还没想通]
我还没有想出如何制作“动态嵌套 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
是一个递归函数。由于闭包,它可以访问 elemIndex
、arr
和 dim
。 elemIndex
指的是从数组arr
.
中读取的当前元素的索引
_nest
取当前维度的索引:dimIndex
。它首先用 0.
调用
- 如果
dimIndex
引用dim
数组中的最后一个维度,则必须返回相应大小的一维数组。这是递归的基本条件。它 returns 从 elemIndex
开始的 arr
的一片,大小 dim[dimIndex]
。
- 否则它使用下一个维度调用
_nest
dim[dimIndex]
次。例如,当 dimIndex 为 0,即大小为 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
的因数时,预计会有意外输出
[我有什么]
具有 n 个元素的扁平化或一维数组,例如数组 A 下面有 12 个项目。
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[我想做什么]
将 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...
[我试过的]
我找到了以下参考资料,它可以按任意行数将展平数组展开为二维数组: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;
}
[我还没想通]
我还没有想出如何制作“动态嵌套 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
是一个递归函数。由于闭包,它可以访问 elemIndex
、arr
和 dim
。 elemIndex
指的是从数组arr
.
_nest
取当前维度的索引:dimIndex
。它首先用 0.
- 如果
dimIndex
引用dim
数组中的最后一个维度,则必须返回相应大小的一维数组。这是递归的基本条件。它 returns 从elemIndex
开始的arr
的一片,大小dim[dimIndex]
。 - 否则它使用下一个维度调用
_nest
dim[dimIndex]
次。例如,当 dimIndex 为 0,即大小为 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