如何优雅实现任意数量JavaScript数组的纵向拼接?
优雅实现嵌套数组按位置合并
需求说明
给定N个长度均为M的嵌套数组,需要将每个对应位置的子数组合并,最终得到M个合并后的数组。例如:
输入:
[ [['a', 'b'], ['c'], ['d']], [['e'], ['f', 'g'], ['h']] ]
输出:
[['a', 'b', 'e'], ['c', 'f', 'g'], ['d', 'h']]
原有方案的问题
你提供的代码存在几个关键问题,导致逻辑失效且边缘场景报错:
concat方法返回新数组,不会修改原数组,因此gatheredData.concat([])和gatheredData[arrayIndex].concat(array)都不会改变gatheredData的内容;- 初始
gatheredData = [[]]的逻辑错误,当遍历第一个数组(arrayIndex=0)时,_.size(gatheredData) < arrayIndex的判断不成立,后续合并逻辑无法正确执行; - 未处理输入为空的边缘场景。
优雅实现方案
原生JavaScript实现
利用map和flatMap组合,简洁完成合并逻辑,同时兼容边缘场景:
const startData = [ [['a', 'b'], ['c'], ['d']], [['e'], ['f', 'g'], ['h']] ]; const merged = startData.length === 0 ? [] : startData[0].map((_, index) => startData.flatMap(arr => arr[index]) ); console.log(merged); // 输出:[['a', 'b', 'e'], ['c', 'f', 'g'], ['d', 'h']]
- 先判断输入是否为空,避免空数组调用
map报错; - 遍历第一个数组的每个索引位置,对每个位置提取所有输入数组对应索引的子数组,并用
flatMap合并成一个数组。
Lodash实现
如果你习惯使用Lodash,可以用_.zip和_.flatMap组合,代码更精简:
const _ = require('lodash'); const startData = [ [['a', 'b'], ['c'], ['d']], [['e'], ['f', 'g'], ['h']] ]; const merged = _.map(_.zip(...startData), _.flatMap); console.log(merged); // 输出:[['a', 'b', 'e'], ['c', 'f', 'g'], ['d', 'h']]
_.zip(...startData)将输入数组的对应位置元素打包成新数组,例如示例中会得到[[['a','b'], ['e']], [['c'], ['f','g']], [['d'], ['h']]];- 再用
_.map遍历每个打包后的数组,通过_.flatMap扁平化合并成目标数组。
内容的提问来源于stack exchange,提问作者PeachWaffle
相关产品推荐
相关产品推荐

