JS中订单数组按日期去重求和的代码优化及控制台疑问
嵌套订单数组聚合与控制台打印问题解答
一、更简洁的实现方式
你的需求是把嵌套的订单数组按日期去重并求和,现有实现可以通过扁平化数组+对象映射+reduce的方式大幅简化,同时提升性能:
优化后代码
groupOrdersByDate(orders: any[]) { // 扁平化嵌套数组,将所有订单合并为一维数组 const flatOrders = orders.flat(); // 用reduce累计每个日期的总金额,对象映射实现O(1)查找 const dateTotalMap = flatOrders.reduce((acc, [dateStr, amount]) => { const formattedDate = new Date(dateStr).toLocaleDateString('fr'); acc[formattedDate] = (acc[formattedDate] || 0) + amount; return acc; }, {} as Record<string, number>); // 将映射对象转换为目标格式的数组 return Object.entries(dateTotalMap).map(([date, total]) => ({ date, total })); }
优化点说明
- 提升性能:原代码每次判断日期是否存在时,需要调用
some、find、findIndex三次遍历数组,时间复杂度较高;用对象映射做累计,查找和更新都是O(1)操作,效率更高。 - 简化逻辑:通过
flat()直接扁平化嵌套数组,省去两层forEach的嵌套;reduce一步完成金额累计,逻辑更集中清晰。 - 去除冗余操作:原代码修改金额后用
splice替换数组元素完全没必要——对象是引用类型,直接修改existingObj.total就会同步更新数组中的对象,不需要额外替换。
二、控制台打印的疑惑:未push元素却显示值?
这是控制台的引用类型实时更新特性导致的:
- 当你调用
console.log(res)时,控制台并不会立即打印数组的当前值快照,而是保存了数组的引用。 - 后续代码往res中push元素后,控制台会自动更新这个引用对应的显示内容,所以你展开控制台的数组时,看到的是数组最终的状态,而不是执行
console.log那一刻的空数组。
如果想查看执行console.log时的真实值,可以打印数组的副本:
// 打印浅拷贝快照,不受后续修改影响 console.log([...res]); // 或者深拷贝(适合复杂嵌套结构) console.log(JSON.parse(JSON.stringify(res)));
内容的提问来源于stack exchange,提问作者EASameh
相关产品推荐
相关产品推荐

