JavaScript多层嵌套数组遍历:替代forEach链式调用的方案咨询
优化多层嵌套数组遍历的方案
针对你提供的多层嵌套数组遍历场景,这里有几个更简洁、可读性更强的等价实现方案:
方案1:使用flatMap链式调用(最简洁)
flatMap可以同时完成映射和扁平化数组的操作,非常适合这种多层嵌套展开的场景,代码更紧凑:
const v = [ { "company_name": "Apple", "company_code": "AP", "states": [ { "state_name": "California", "state_code": "CA", "locations": [ { "location_name": "USA - New York", "location_code": "US - NY" }, { "location_name": "USA - San Francisco", "location_code": "US - SF" } ] }, { "state_name": "Rajasthan", "state_code": "RJ", "locations": [ { "location_name": "Udaipur", "location_code": "UDR" }, { "location_name": "Jaipur", "location_code": "JP" } ] } ] } ]; const AllData = v.flatMap(company => company.states.flatMap(state => state.locations.map(location => ({ companyname: company.company_name, statename: state.state_name, locationname: location.location_name })) ) ); console.log(AllData);
说明:
- 第一层
flatMap遍历公司数组,返回每个公司对应的所有状态处理后的数组 - 第二层
flatMap遍历每个公司的状态数组,返回每个状态对应的所有地点处理后的数组 - 最内层
map把每个地点对象转换成我们需要的结构 - 全程不需要手动初始化空数组和调用
push,代码更符合函数式编程风格
方案2:使用递归函数(适配不确定嵌套层数)
如果未来嵌套层级可能变化(比如新增更多层级),递归方案更灵活,不需要修改遍历逻辑:
const v = [/* 原数组内容 */]; function flattenNestedData(arr) { const result = []; function traverse(item) { // 判断当前项是否包含locations(最底层节点) if (item.locations) { item.locations.forEach(location => { result.push({ companyname: item.company_name || result[result.length-1]?.companyname, statename: item.state_name || result[result.length-1]?.statename, locationname: location.location_name }); }); } // 判断当前项是否包含子层级数组 else if (Array.isArray(item.states)) { item.states.forEach(state => { // 传递上层的公司信息 traverse({...state, company_name: item.company_name}); }); } // 处理最外层的公司数组 else { item.forEach(company => traverse(company)); } } traverse(arr); return result; } const AllData = flattenNestedData(v); console.log(AllData);
说明:
- 递归函数会自动识别层级结构,不管未来新增多少层嵌套,只要保持类似的层级字段(如
states、locations),就能自动适配 - 适合结构可能变化的场景,扩展性更强
方案3:使用reduce结合forEach(兼容旧环境)
如果需要兼容不支持flatMap的旧JavaScript环境,可以用reduce来替代:
const v = [/* 原数组内容 */]; const AllData = v.reduce((acc, company) => { company.states.forEach(state => { state.locations.forEach(location => { acc.push({ companyname: company.company_name, statename: state.state_name, locationname: location.location_name }); }); }); return acc; }, []); console.log(AllData);
说明:
- 用
reduce初始化空数组并累积结果,逻辑和原代码类似,但去掉了外层的for循环,代码更简洁
内容的提问来源于stack exchange,提问作者Maahi
相关产品推荐
相关产品推荐

