JavaScript订单各产品类型累计数量统计及代码优化咨询
优化订单产品类型数量统计代码
嘿,我来帮你优化这段统计订单产品类型数量的代码~先聊聊原代码里的几个小问题,再给出更简洁优雅的实现:
原代码的问题点
- 用数组存储统计结果不合适:你用
newArray来存产品类型的总数量,但产品类型是字符串(比如"A"、"B"),用数组的话本质是利用了JS数组也是对象的特性,但语义上完全不对,而且容易造成误解。 - reduce用法有误:你把reduce的初始值设为
0,但后续返回的是数组,累加器类型不统一;而且你依赖外部的newArray变量,没有真正利用reduce的累加器特性,这其实违背了reduce的设计初衷。 - 直接修改原对象:你直接给原订单对象
h添加orderDetails_属性,会污染原数据,在很多场景下这是不安全的。 - 逻辑冗余:if-else判断可以简化,不用写这么复杂。
另外还要提一下你的示例数据有个小错误:orderDetails里的对象重复定义了quantity和product键,在JS里后面的键会覆盖前面的,所以正确的示例数据应该是每个明细是独立对象,比如:
const data = [{ "order": 1, "orderDetails": [ { "quantity": 10, "product": { "productType": "A" } }, { "quantity": 20, "product": { "productType": "A" } }, { "quantity": 10, "product": { "productType": "B" } } ] }];
优化后的代码
const orders = data.map(order => { // 用reduce统计各产品类型的总数量,累加器是语义化的对象 const productTypeTotals = order.orderDetails.reduce((acc, detail) => { const type = detail.product.productType; // 简化累加逻辑:第一次出现的类型初始为0,再加当前数量 acc[type] = (acc[type] || 0) + detail.quantity; return acc; }, {}); // 初始值设为空对象,和累加器类型统一 // 返回新对象,避免修改原数据,属性名更直观 return { ...order, productTypeTotals }; });
优化点说明
- 正确使用reduce:用空对象作为reduce的初始值,累加器
acc全程是对象,每一步都基于当前明细更新对应类型的数量,完全利用了reduce的累加特性,不再依赖外部变量。 - 简化逻辑:
(acc[type] || 0)巧妙处理了类型第一次出现的情况,省去了if-else判断,代码更简洁。 - 不污染原数据:用扩展运算符
...order复制原订单的所有属性,再添加统计结果productTypeTotals,返回全新的对象,避免修改原数据。 - 语义化命名:把
orderDetails_改成productTypeTotals,一眼就能看出这个属性的含义,可读性更强。
运行优化后的代码,对于修正后的示例数据,会得到这样的结果:
[ { "order": 1, "orderDetails": [...], "productTypeTotals": { "A": 30, "B": 10 } } ]
内容的提问来源于stack exchange,提问作者NikOs
相关产品推荐
相关产品推荐

