如何基于title属性合并对象到数组并累加amount值?
优雅实现基于Title合并对象到数组并累加Amount的方案
你的需求很明确:将一个对象合并到数组中,依据title属性判断,若存在相同title的元素则累加amount,不存在则直接添加。现有方案是可行的,但确实可以通过减少数组遍历次数或者利用更高效的数据结构来优化,让代码更简洁优雅。
先回顾下你的需求示例:
初始数组:
let items = [{"title":"x","amount":1}, {"title":"y","amount":1}, {"title":"z","amount":1}];待合并对象:
let obj1 = {"title":"x","amount":2};预期结果:
[{"title":"x","amount":3}, {"title":"y","amount":1}, {"title":"z","amount":1}]
你的现有实现虽然能完成功能,但做了两次数组遍历(some和find),我们可以优化成一次遍历,或者用Map来提升查找效率,下面提供几种更优雅的写法:
方案一:使用findIndex减少遍历次数
只需要一次定位到目标元素的索引,既可以判断是否存在,又能直接操作元素,代码更简洁:
mergeResponses(x) { const index = this.items.findIndex(item => item.title === x.title); if (index === -1) { this.items.push(x); } else { this.items[index].amount += x.amount; } }
这个方案把原来的两次遍历(some+find)变成了一次findIndex调用,性能和代码简洁度都有提升。
方案二:使用Map实现高效查找(适合大数据量场景)
如果你的数组元素很多,多次调用合并操作的话,用Map来存储以title为键的元素,查找时间复杂度从O(n)降到O(1),效率更高:
mergeResponses(x) { // 先把数组转成Map(可以只做一次,比如在初始化或者首次调用时) const itemMap = new Map(this.items.map(item => [item.title, item])); if (itemMap.has(x.title)) { itemMap.get(x.title).amount += x.amount; } else { itemMap.set(x.title, x); this.items.push(x); } // 如果需要保持数组和Map同步,也可以直接从Map生成新数组: // this.items = Array.from(itemMap.values()); }
这种方式在频繁合并的场景下优势明显,避免了每次都遍历整个数组。
方案三:使用数组的find方法一次获取元素
和方案一类似,直接用find找到目标元素,省去some的判断:
mergeResponses(x) { const existingItem = this.items.find(item => item.title === x.title); if (existingItem) { existingItem.amount += x.amount; } else { this.items.push(x); } }
这个写法非常直观,代码量最少,逻辑清晰易懂,对于中小规模的数组来说完全够用。
对比你的原始实现,这几种方案都减少了不必要的数组遍历,代码更简洁易读,同时保持了功能的完整性。
内容的提问来源于stack exchange,提问作者Zcauchon
相关产品推荐
相关产品推荐

