如何将嵌套数组拆分为大小有限的 "rows"
How to split nested array into "rows" with limited size
我有一组不同大小的数组。目标是生成“行”,其中每行最多可包含 12 个元素。
例如:
输入数据可以是这样的:
const groups = [[1,2,3,4],[1,2,3,4,5,6], [1,2,3,4,5,6,7,8,9,10,11,12], [1,2,3,4,5,6,7], [1,2,3],[1,2,3]]
groups[0].length + groups[1].length = 10 -> row0
groups[2].length = 12 -> row1
groups[3].length + groups[4].length = 10 -> row3
groups[5].length = 3 -> row4
此类数组的输出应为:
[[[1,2,3,4], [1,2,3,4,5,6]], [[1,2,3,4,5,6,7,8,9,10,11,12]], [[1,2,3,4,5,6,7], [1,2,3]], [[1,2,3]]]
我正在考虑为此使用递归函数,但无法弄清楚如何解决它。
您可以使用 Array#reduce()
来执行此操作。
如果添加下一组,代码首先检查当前最后一个元素(最后“行”)中的数字是否超过 12 个:
(acc[acc.length - 1].flat().length + cv.length) <= 12
如果小于 12,元素将被推入“行”:
acc[acc.length - 1].push(cv)
如果没有,一个新的“行”将添加到外部数组:
acc.push([cv])
const groups = [[1, 2, 3, 4],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],[1, 2, 3, 4, 5, 6, 7],[1, 2, 3],[1, 2, 3]];
const rows = groups.reduce((acc, cv) => {
(acc[acc.length - 1].flat().length + cv.length) <= 12 ?
acc[acc.length - 1].push(cv) :
acc.push([cv])
return acc
}, [[]]);
console.log(JSON.stringify(rows))
这是递归求解的一种方法:
const regroup = (max, [g, ...gs], filled = [], curr = [], cc = 0) =>
g == undefined
? filled .concat ([curr])
: g .length + cc <= max
? regroup (max, gs, filled, curr .concat ([g]), cc + g.length)
: regroup (max, gs, filled .concat ([curr]), [g], g .length)
const groups = [[1, 2, 3, 4], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[1, 2, 3, 4, 5, 6, 7], [1, 2, 3], [1, 2, 3]]
console .log (regroup (12, groups))
.as-console-wrapper {max-height: 100% !important; top: 0}
我们传递了最大尺寸和项目列表,然后我们默认了三个参数:
filled
将跟踪我们填充的输出行;它以一个空数组开始
curr
存储我们正在处理的行;它也以一个空数组开始
cc
存储当前行所有元素的个数;它从零开始
在每次递归调用中,我们有以下三种可能性之一:
- 没有更多的数组要处理,我们 return 所有填充的行都附加了当前行。
- 下一个数组足够小以适合当前行,我们更新当前以包含它,并更新当前计数以容纳它。
- 下一个数组太大,我们将现有的当前行添加到已填充的行,并以此数组开始一个新的当前行,适当设置计数。
我有一组不同大小的数组。目标是生成“行”,其中每行最多可包含 12 个元素。 例如:
输入数据可以是这样的:
const groups = [[1,2,3,4],[1,2,3,4,5,6], [1,2,3,4,5,6,7,8,9,10,11,12], [1,2,3,4,5,6,7], [1,2,3],[1,2,3]]
groups[0].length + groups[1].length = 10 -> row0
groups[2].length = 12 -> row1
groups[3].length + groups[4].length = 10 -> row3
groups[5].length = 3 -> row4
此类数组的输出应为:
[[[1,2,3,4], [1,2,3,4,5,6]], [[1,2,3,4,5,6,7,8,9,10,11,12]], [[1,2,3,4,5,6,7], [1,2,3]], [[1,2,3]]]
我正在考虑为此使用递归函数,但无法弄清楚如何解决它。
您可以使用 Array#reduce()
来执行此操作。
如果添加下一组,代码首先检查当前最后一个元素(最后“行”)中的数字是否超过 12 个:
(acc[acc.length - 1].flat().length + cv.length) <= 12
如果小于 12,元素将被推入“行”:
acc[acc.length - 1].push(cv)
如果没有,一个新的“行”将添加到外部数组:
acc.push([cv])
const groups = [[1, 2, 3, 4],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],[1, 2, 3, 4, 5, 6, 7],[1, 2, 3],[1, 2, 3]];
const rows = groups.reduce((acc, cv) => {
(acc[acc.length - 1].flat().length + cv.length) <= 12 ?
acc[acc.length - 1].push(cv) :
acc.push([cv])
return acc
}, [[]]);
console.log(JSON.stringify(rows))
这是递归求解的一种方法:
const regroup = (max, [g, ...gs], filled = [], curr = [], cc = 0) =>
g == undefined
? filled .concat ([curr])
: g .length + cc <= max
? regroup (max, gs, filled, curr .concat ([g]), cc + g.length)
: regroup (max, gs, filled .concat ([curr]), [g], g .length)
const groups = [[1, 2, 3, 4], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[1, 2, 3, 4, 5, 6, 7], [1, 2, 3], [1, 2, 3]]
console .log (regroup (12, groups))
.as-console-wrapper {max-height: 100% !important; top: 0}
我们传递了最大尺寸和项目列表,然后我们默认了三个参数:
filled
将跟踪我们填充的输出行;它以一个空数组开始curr
存储我们正在处理的行;它也以一个空数组开始cc
存储当前行所有元素的个数;它从零开始
在每次递归调用中,我们有以下三种可能性之一:
- 没有更多的数组要处理,我们 return 所有填充的行都附加了当前行。
- 下一个数组足够小以适合当前行,我们更新当前以包含它,并更新当前计数以容纳它。
- 下一个数组太大,我们将现有的当前行添加到已填充的行,并以此数组开始一个新的当前行,适当设置计数。