
本文介绍如何使用 JavaScript 的 flatMap() 链式调用高效提取深层嵌套结构(如 consignments → shipping/downloads → line_items)中所有 sku 字段值,生成扁平化结果数组。
本文介绍如何使用 javascript 的 `flatmap()` 链式调用高效提取深层嵌套结构(如 `consignments → shipping/downloads → line_items`)中所有 `sku` 字段值,生成扁平化结果数组。
在实际电商或订单系统开发中,JSON 数据常存在多层嵌套结构,例如一个订单对象包含多个货件(consignments),每个货件下又分 shipping(实物发货项)和 downloads(数字下载项),而商品 SKU 信息则深藏于各自的 line_items 数组中。要一次性提取所有 sku 值(如 ["ABS", "OCG", "OFSUC"]),传统 for 循环易出错且冗长;而合理组合 flatMap() 可实现声明式、可读性强且高效率的提取。
核心思路是:逐层“摊平”嵌套关系,再映射提取目标字段。具体步骤如下:
-
顶层遍历
consignments:使用flatMap()遍历每个货件(避免返回二维数组); -
合并同级数组:对每个货件,将
shipping和downloads合并为单一数组(concat),二者结构一致(均含line_items); -
二级摊平与提取:对合并后的数组,用
flatMap()遍历每个子项(如 shipping 对象或 download 对象),再对其line_items执行flatMap()提取sku—— 若某line_items为空,flatMap自动跳过,无需额外判空; -
自动去除非数组/undefined:
flatMap对undefined或非数组返回值会忽略,确保结果纯净。
以下是完整、健壮的实现代码:
const getSkuArray = (data) => {
if (!data || !Array.isArray(data.consignments)) {
return [];
}
return data.consignments.flatMap(consignment => {
// 安全合并 shipping 和 downloads(兼容可能缺失的字段)
const sources = [
...(Array.isArray(consignment.shipping) ? consignment.shipping : []),
...(Array.isArray(consignment.downloads) ? consignment.downloads : [])
];
return sources.flatMap(item =>
Array.isArray(item.line_items)
? item.line_items.flatMap(lineItem => lineItem.sku)
: []
);
});
};
// 使用示例
const skuResult = getSkuArray(jsonObject);
console.log(skuResult); // ["ABS", "OCG", "OFSUC"]✅ 优势说明:
- ✅ 零副作用:纯函数式,不修改原始数据;
- ✅ 强容错性:显式检查
Array.isArray(),避免Cannot read property 'flatMap' of undefined错误; - ✅ 语义清晰:
flatMap天然表达“展开 + 映射”,比嵌套map().flat()更简洁; - ✅ 性能友好:单次遍历完成全部提取,时间复杂度 O(n),无冗余循环。
⚠️ 注意事项:
- 若
sku字段可能为null或undefined,可在最终映射中增加过滤:.flatMap(lineItem => lineItem.sku ?? null).filter(sku => sku !== null); - 如需去重,末尾追加
.filter((v, i, a) => a.indexOf(v) === i); - 浏览器兼容性:
flatMap支持现代浏览器及 Node.js ≥11;旧环境可用 Babel 转译或替换为reduce+concat组合。
掌握这种嵌套数组的链式摊平技巧,可显著提升处理复杂 API 响应的开发效率与代码健壮性。


















