求最优JavaScript/TS实现:计算各基础商品总数量
高效合并购物车同基础商品数量求和
我需要最高效的方法,遍历购物车商品列表,将指向同一基础商品(BaseItem)的所有购物车商品(CartItem)的数量求和,得到每个基础商品的总数量。
接口定义
export interface CartItem { id: string; baseItem: BaseItem; quantity: number; addOns: string[] } export interface BaseItem { name: string; id: string; }
同一基础商品可能对应多个不同附加项(AddOns/Variations)的CartItem。我当前使用Map实现了需求,但想找更高效的优化方案,现有代码如下:
const itemQuantites: Map<string, number> = new Map<string, number>(); cart.items.forEach( cartItem => { // Check for a match, else add it to the Map if (itemQuantites.has(cartItem.baseItem.id)) { const currentQuantity = itemQuantites.get(cartItem.baseItem.id) ?? 0; itemQuantites.set(cartItem.baseItem.id, currentQuantity + cartItem.quantity); } else { itemQuantites.set(cartItem.baseItem.id, cartItem.quantity); } } );
优化方案
你的初始实现已经是时间复杂度最优的O(n)(必须遍历所有商品一次),但可以通过简化逻辑减少不必要的方法调用,提升常数时间性能:
简化Map实现
省去has判断,直接通过get获取当前值(不存在则取0),一次完成累加和赋值:
const itemQuantities = new Map<string, number>(); cart.items.forEach(cartItem => { const baseId = cartItem.baseItem.id; itemQuantities.set(baseId, (itemQuantities.get(baseId) ?? 0) + cartItem.quantity); });
用for...of替代forEach(大数据量下略快)
forEach存在函数调用开销,大数据量时用for...of循环性能更优:
const itemQuantities = new Map<string, number>(); for (const cartItem of cart.items) { const baseId = cartItem.baseItem.id; itemQuantities.set(baseId, (itemQuantities.get(baseId) || 0) + cartItem.quantity); }
用普通对象替代Map(键为字符串时可选)
如果基础商品ID都是合法的对象键(无特殊字符),普通对象的存取性能在部分JS引擎下略优于Map:
const itemQuantities: Record<string, number> = {}; for (const cartItem of cart.items) { const baseId = cartItem.baseItem.id; itemQuantities[baseId] = (itemQuantities[baseId] || 0) + cartItem.quantity; }
总结
无论哪种写法,核心逻辑都是O(n)的遍历+O(1)的键值存取,这已经是理论上的最优复杂度。优化的核心是减少不必要的方法调用(比如去掉has判断),以及选择更高效的遍历方式,在大数据量场景下能带来轻微的性能提升。
内容的提问来源于stack exchange,提问作者Arnaw Gundawar
相关产品推荐
相关产品推荐

