flatMap()是映射与扁平化一步到位的操作,专用于拆解嵌套结构(如订单含商品数组),比map后flat(1)更语义清晰、性能更优、链式更简洁。

flatMap() 是处理嵌套结构数据的利器,尤其适合拆解 API 返回的“资源列表中含子资源数组”的复合场景——它一步完成映射(map)与扁平化(flat),比先 map 再 flat(1) 更简洁、更语义清晰。
理解典型复合结构:资源带关联子项
很多 REST API(如订单系统、文章+标签、用户+权限)返回类似这样的结构:
[
{
id: 1,
title: "订单A",
items: [{ name: "iPhone", qty: 1 }, { name: "充电线", qty: 2 }]
},
{
id: 2,
title: "订单B",
items: [{ name: "MacBook", qty: 1 }]
}
]
若需提取所有商品(不分订单),传统做法需两步:map(x => x.items).flat();而 flatMap() 直接一气呵成。
基础用法:一行展开所有子项
对每个对象提取 items 数组,并自动压平一层:
const allItems = orders.flatMap(order => order.items);
// → [{ name: "iPhone", qty: 1 }, { name: "充电线", qty: 2 }, { name: "MacBook", qty: 1 }]
注意:返回值必须是数组;若回调返回非数组(如 null 或字符串),会转为空数组 [],不会报错。
增强转换:在展开时注入上下文信息
常需保留父级 ID、名称等上下文。可在映射时为每个子项添加字段:
const enrichedItems = orders.flatMap(order =>
order.items.map(item => ({
...item,
orderId: order.id,
orderTitle: order.title
}))
);
// → [
// { name: "iPhone", qty: 1, orderId: 1, orderTitle: "订单A" },
// { name: "充电线", qty: 2, orderId: 1, orderTitle: "订单A" },
// { name: "MacBook", qty: 1, orderId: 2, orderTitle: "订单B" }
// ]
过滤 + 展开:跳过空或无效子项
当某些资源的 items 可能为 null、undefined 或空数组时,可结合条件逻辑安全处理:
- 显式检查:
order.items?.map(...)或order.items || [] - 利用 flatMap 的“空数组友好”特性:直接返回
[]即跳过该元素
const validItems = orders.flatMap(order =>
Array.isArray(order.items) && order.items.length > 0
? order.items.map(i => ({ ...i, at: new Date() }))
: []
);
对比 flat(1) + map:为什么 flatMap 更优雅?
虽然 orders.map(...).flat(1) 功能等价,但 flatMap 有明显优势:
- 语义明确:意图是“映射并扁平”,而非“映射后手动扁平”
- 性能略优:避免中间数组创建(V8 等引擎已做优化)
- 链式更干净:尤其在长管道中(如
fetch().then(r => r.json()).then(data => data.results.flatMap(...)))
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










