优化JavaScript中多reduce和map提取嵌套对象数据的方法
优化嵌套对象数组的数据提取代码
嘿,你的代码功能没问题,但确实可以通过JS的现代特性让它更简洁优雅!先把你没写完的代码补全(假设你是要提取学校名称和地址详情),然后给你几个优化方案:
你的原始代码(补全后)
我正在从嵌套对象数组中提取数据,当前用两个reduce加map的方式实现,功能正常但代码不够优雅。请问如何优化这段代码?
我的代码如下:
function extractSchools(schools) { let schoolData = []; if (schools) { schoolData = schools.reduce(function(parentdata, chlrn) { let childrenlist = chlrn.children; let childrendata = []; if (childrenlist) { childrendata = childrenlist.reduce(function(addrsslist, school) { return addrsslist.concat(school.address.map(i => ({ schoolName: school.name, addressDetail: i.detail, city: i.city }))); }, []); } return parentdata.concat(childrendata); }, []); } return schoolData; }
优化方案1:用flatMap替代嵌套reduce+concat
flatMap是专门用来处理“映射后扁平化”的场景,完美匹配你现在的嵌套遍历需求,代码会清爽很多:
function extractSchools(schools) { if (!schools) return []; return schools.flatMap(chlrn => { // 如果当前项没有children,直接返回空数组跳过 if (!chlrn.children) return []; // 遍历子学校,再遍历每个学校的地址,最后扁平化结果 return chlrn.children.flatMap(school => school.address.map(i => ({ schoolName: school.name, addressDetail: i.detail, city: i.city })) ); }); }
为什么这更好?
- 去掉了一堆冗余的临时变量(比如
parentdata、childrendata),逻辑链更清晰 flatMap的语义很直观:先把每个父元素映射成子数组,再把所有子数组合并成一个大数组,完全对应你“取父级→取子学校→取地址”的流程- 提前做空值判断,避免无效遍历
优化方案2:用可选链+箭头函数进一步精简(ES2020+)
如果你的项目环境支持ES2020及以上的语法,用可选链(?.)和空值合并(??)可以把代码压缩得更紧凑,同时可读性依然在线:
const extractSchools = (schools) => schools?.flatMap(chlrn => chlrn.children?.flatMap(school => school.address.map(i => ({ schoolName: school.name, addressDetail: i.detail, city: i.city })) ) ?? [] ) ?? [];
亮点
- 箭头函数让代码更简洁,去掉了冗余的
function和大括号 - 可选链
?.自动处理schools、chlrn.children为null/undefined的情况,不用写一堆if判断 - 空值合并
??确保空值场景下返回空数组,保证函数返回值始终是数组类型
优化方案3:通用递归提取(适配更深嵌套)
如果未来你的数据结构可能有多层嵌套的children,写一个递归函数会更灵活,不用每次加层级都改代码:
function extractSchools(schools) { if (!schools) return []; // 定义递归提取的辅助函数 const extractItems = (items) => items.flatMap(item => { // 如果当前项有children,递归处理子项 if (item.children) { return extractItems(item.children); } // 处理最底层的学校地址 return item.address?.map(i => ({ schoolName: item.name, addressDetail: i.detail, city: i.city })) ?? []; }); return extractItems(schools); }
适用场景
- 数据结构的嵌套层级不固定,可能有3层甚至更多的
children - 希望代码有扩展性,未来结构变化时不用大改核心逻辑
内容的提问来源于stack exchange,提问作者jacky
相关产品推荐
相关产品推荐

