JavaScript如何对对象数组中同键的total属性值求和
动态键对象数组同键total值累加实现
你需要的统计逻辑不需要先分组再求和,直接遍历累加即可,以下分别提供Lodash和原生JS的实现方式,均支持动态生成的未知键名。
Lodash 实现
最简洁的写法是用_.reduce配合_.forIn遍历,不需要额外做格式转换:
import _ from 'lodash' const dataset = [ { a: { total: 2, name: "red" }, b: { total: 3, name: "gold" }, c: { total: 6, name: "rose" }, }, { a: { total: 10, name: "red" }, b: { total: 7, name: "purple" }, }, { a: { total: 1, name: "pink" }, b: { total: 14, name: "blue" }, c: { total: 10, name: "rose" }, }, { b: { total: 2, name: "green" }, c: { total: 18, name: "rose" }, }, ] const result = _.reduce(dataset, (acc, currItem) => { // 遍历当前项的所有键,不管键名是什么 _.forIn(currItem, (value, key) => { acc[key] = (acc[key] || 0) + value.total }) return acc }, {}) // 输出结果:{a: 13, b: 26, c: 34}
如果偏好函数式合并的写法,也可以用_.mergeWith自定义合并规则,最后提取total值即可:
const merged = _.mergeWith({}, ...dataset, (prev, next) => { if (prev) return { total: prev.total + next.total } }) const result = _.mapValues(merged, item => item.total)
原生JS 实现
不依赖第三方库的写法逻辑完全一致,用原生reduce和Object.entries就能实现:
const result = dataset.reduce((acc, currItem) => { for (const [key, value] of Object.entries(currItem)) { acc[key] = (acc[key] ?? 0) + value.total } return acc }, {})
兼容提示:如果运行环境不支持ES2020的空值合并运算符
??,替换为acc[key] || 0即可。
实现说明
- 遍历过程中直接通过累加器存储每个键的累计值,省去了先分组的额外步骤,性能更高
- 自动适配任意数量的动态键,不需要提前枚举键名
- 自动兼容数组项缺失部分键的场景,不会抛出属性不存在的错误
内容的提问来源于stack exchange,提问作者marielle
相关产品推荐
相关产品推荐

