如何不使用传统for循环将扁平表格JSON数据转换为主从层级结构
扁平订单JSON转主从层级结构的优化实现方案
我们需要把包含重复主订单信息的扁平表格JSON,聚合为主订单+明细列表的主从层级结构,除了常规for循环外,有以下几种更简洁高效的实现方式:
方法1:Array.reduce 单遍历实现(原生JS无依赖,时间复杂度O(n))
这是最常用的原生替代方案,仅需一次遍历即可完成聚合,代码简洁语义化强:
const flatData = [/* 输入的扁平JSON数据 */]; const result = Object.values(flatData.reduce((acc, cur) => { // 按orderid分组,不存在则初始化主订单结构 if (!acc[cur.orderid]) { acc[cur.orderid] = { orderid: cur.orderid, grandtotal: cur.grandtotal, details: [] }; } // 存在明细字段则推入details数组 if (cur.detailid) { acc[cur.orderid].details.push({ detailid: cur.detailid, description: cur.description }); } return acc; }, {}));
方法2:Map 分组映射实现(逻辑分层清晰,便于后续扩展)
如果后续需要对订单做增删改查操作,用Map存储映射关系更方便操作,性能也优于普通对象:
const flatData = [/* 输入的扁平JSON数据 */]; const orderMap = new Map(); flatData.forEach(item => { if (!orderMap.has(item.orderid)) { orderMap.set(item.orderid, { orderid: item.orderid, grandtotal: item.grandtotal, details: [] }); } if (item.detailid) { orderMap.get(item.orderid).details.push({ detailid: item.detailid, description: item.description }); } }); // 转换为最终数组格式 const result = Array.from(orderMap.values());
方法3:借助lodash工具库实现(业务场景下快速编码)
如果项目允许引入第三方工具库,用lodash的封装方法可以进一步减少编码量,降低出错概率:
const _ = require('lodash'); const flatData = [/* 输入的扁平JSON数据 */]; // 先按orderid分组 const grouped = _.groupBy(flatData, 'orderid'); // 遍历分组生成最终结构 const result = _.map(grouped, items => ({ orderid: items[0].orderid, grandtotal: items[0].grandtotal, details: items.filter(item => item.detailid).map(item => _.pick(item, ['detailid', 'description'])) }));
方案优势
- 所有方案均为单次遍历,时间复杂度为O(n),性能远高于嵌套for循环的O(n²)实现
- 代码语义化更强,便于后续维护迭代
- 无多余全局变量定义,内存占用更低
内容的提问来源于stack exchange,提问作者Jeb50
相关产品推荐
相关产品推荐

