JavaScript中如何用reduce聚合数组对象的多个字段值?
问题:按item字段分组并聚合多字段数值
需要处理如下结构的对象数组:
var data = [{ item: "Item 1", pages: 30, chapters: 3 }, { item: "Item 1", pages: 50, chapters: 3 }, { item: "Item 2", pages: 10, chapters: 3 } ]
要求按item字段分组,同时聚合pages和chapters两个字段的数值,期望结果:
[ {item: "Item 1", pages: 80, chapters: 6}, {item: "Item 2", pages: 10, chapters: 3} ]
尝试用reduce方法实现,但报错提示找不到pages项,代码如下:
data.reduce((acc,cur) => { acc[cur.item][pages] = acc[cur.item][pages] + cur.item.pages || cur.item.pages acc[cur.item][chapters] = acc[cur.item][chapters] + cur.item.chapters || cur.item.chapters return acc },{})
请问是否可以使用reduce方法来聚合多个字段的数据?
解答
完全可以用reduce实现多字段聚合,你的代码存在几个问题:
- 累加器初始为空对象,首次处理时
acc[cur.item]不存在,直接访问其属性会报错 pages和chapters没有加引号,会被当作变量而非字符串键名- 错误使用
cur.item.pages,应该是cur.pages(cur.item是字符串,没有pages属性) - 逻辑或的写法可能在数值为0时出现意外,建议用更严谨的判断
以下是修正后的实现:
const result = Object.values(data.reduce((acc, cur) => { // 如果当前item还未在累加器中,初始化对应的对象 if (!acc[cur.item]) { acc[cur.item] = { item: cur.item, pages: 0, chapters: 0 }; } // 累加对应字段的值 acc[cur.item].pages += cur.pages; acc[cur.item].chapters += cur.chapters; return acc; }, {}));
代码说明:
- 用
reduce构建一个以item为键的临时对象,键值是聚合后的对象 - 每次迭代时,先检查当前
item是否已存在于累加器,不存在则初始化结构 - 直接累加
pages和chapters的数值 - 最后用
Object.values()把临时对象的取值转换成数组,得到期望结果
内容的提问来源于stack exchange,提问作者Ikzer
相关产品推荐
相关产品推荐

