JavaScript:如何扁平化对象数组中的嵌套数组结构?
问题:扁平化包含数组属性的对象数组
我正在尝试在JavaScript中扁平化一种特殊结构的数组:数组的每个元素都是对象,每个对象里都包含一个numbers数组。示例输入如下:
[{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]
我希望将它扁平化为一维数组:[1, 2, 3, 4, 5, 6]。
我已经有了一个可行的解决方案:
const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]; const almostFlattened = arr.map((obj) => obj.numbers); const flattened = [].concat.apply([], almostFlattened); console.log(flattened); // 输出 [1, 2, 3, 4, 5, 6]
想问问有没有更优的实现方式?
更优实现方案
当然有!随着JavaScript标准的更新,现在有很多更简洁、可读性更强的方法来完成这个需求,下面推荐几种常用的方案:
1. 使用Array.prototype.flatMap(最简洁)
flatMap可以看作是map之后立即执行一层flat,正好适配你的场景,一步就能完成转换:
const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]; const flattened = arr.flatMap(obj => obj.numbers); console.log(flattened); // 输出 [1, 2, 3, 4, 5, 6]
这种方式代码量最少,逻辑清晰,直接表达了“映射每个对象的numbers数组并扁平化”的意图,是现代环境下的首选方案。
2. 使用Array.prototype.map + Array.prototype.flat
如果你的环境支持ES2019及以上,也可以分开写map和flat,可读性同样不错:
const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]; const flattened = arr.map(obj => obj.numbers).flat(); // 或者明确指定扁平化层数,这里是1层,和默认效果一样 // const flattened = arr.map(obj => obj.numbers).flat(1); console.log(flattened); // 输出 [1, 2, 3, 4, 5, 6]
这种方式比你的原始方案更直观,flat方法替代了concat.apply,语义更明确。
3. 使用Array.prototype.reduce
如果你需要兼容更老的环境(不支持ES2019),reduce也是一个不错的选择,它不需要额外的中间数组:
const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]; const flattened = arr.reduce((acc, obj) => acc.concat(obj.numbers), []); console.log(flattened); // 输出 [1, 2, 3, 4, 5, 6]
这种方式将映射和合并的逻辑放在一个步骤里,避免了创建中间数组almostFlattened,内存效率更高一些。
内容的提问来源于stack exchange,提问作者Jack Ryan
相关产品推荐
相关产品推荐

