如何在JavaScript中按日期聚合对象数组的主题与计数?
按日期分组转换对象数组结构
我有一个包含created_at、topic和count字段的对象数组,需要将其转换为按日期分组的结构:每个日期对应一个对象,以各类topic作为键,对应的count数值作为值。我尝试用reduce方法实现,以下是原始数组和期望转换结果:
原始数组
const myObj = [ { "created_at": "2022-06-12T18:30:00.000Z", "topic": "Technical_support/Installation", "count": "2" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "pricing", "count": "1" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "Product/sales enquiry", "count": "1" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "Service", "count": "4" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "others", "count": "1" }, { "created_at": "2022-06-12T18:30:00.000Z", "topic": "Product/sales enquiry", "count": "5" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "Service", "count": "28" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "Billing/order", "count": "1" }, { "created_at": "2022-06-12T18:30:00.000Z", "topic": "Service", "count": "11" }, { "created_at": "2022-06-12T18:30:00.000Z", "topic": "others", "count": "5" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "Technical_support/Installation", "count": "1" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "pricing", "count": "6" }, { "created_at": "2022-06-12T18:30:00.000Z", "topic": "pricing", "count": "1" }, { "created_at": "2022-06-10T18:30:00.000Z", "topic": "offer", "count": "1" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "Product/sales enquiry", "count": "4" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "offer", "count": "1" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "others", "count": "15" }, { "created_at": "2022-06-11T18:30:00.000Z", "topic": "Technical_support/Installation", "count": "10" } ]
期望转换结果
(注:你提供的示例结果中部分数值与原始数组不符,以下是基于原始数组计算出的正确结果)
[ { date: "2022-06-10T18:30:00.000Z", "Technical_support/Installation": 1, pricing: 1, "Product/sales enquiry": 1, Service: 4, others: 1, offer: 1 }, { date: "2022-06-11T18:30:00.000Z", Service: 28, "Billing/order": 1, pricing: 6, "Product/sales enquiry": 4, offer: 1, others: 15, "Technical_support/Installation": 10 }, { date: "2022-06-12T18:30:00.000Z", "Technical_support/Installation": 2, "Product/sales enquiry": 5, Service: 11, others: 5, pricing: 1 } ];
实现方案
基础分组实现
使用Array.reduce()完成分组,同时将字符串类型的count转为数字:
const groupedByDate = Object.values(myObj.reduce((acc, item) => { const date = item.created_at; // 初始化当前日期的对象 if (!acc[date]) { acc[date] = { date }; } // 赋值或累加count数值 acc[date][item.topic] = (acc[date][item.topic] || 0) + Number(item.count); return acc; }, {}));
包含所有Topic的实现
如果需要每个日期对象都包含所有出现过的topic(无数据时显示0),可以先收集所有唯一topic再初始化:
// 提取所有唯一的topic const allTopics = [...new Set(myObj.map(item => item.topic))]; const groupedByDateWithAllTopics = Object.values(myObj.reduce((acc, item) => { const date = item.created_at; if (!acc[date]) { // 初始化时给所有topic设置默认值0 acc[date] = allTopics.reduce((topicAcc, topic) => { topicAcc[topic] = 0; return topicAcc; }, { date }); } // 累加对应topic的count acc[date][item.topic] += Number(item.count); return acc; }, {}));
代码说明
- reduce累加器:用空对象存储日期到对应数据对象的映射。
- 日期分组:遍历每个元素,以
created_at为键,不存在则创建包含date字段的对象。 - 数值处理:将
count转为数字,若当前topic已存在则累加,否则从0开始累加。 - 转换为数组:通过
Object.values()将累加器中的对象提取为最终的数组结构。
内容的提问来源于stack exchange,提问作者Priyansh Sharma
相关产品推荐
相关产品推荐

