如何使用reduce对比数组构建适配图表的数组对象
问题:图表数据格式转换与缺失值填充
我需要填充图表数据,按特定格式处理时发现存在数据缺失情况。
现有日期数组:
const labels = ["Sep.08", "Sep.09", "Sep.12", "Sep.13", "Sep.14"]
以及包含name、date和count的对象数组:
const Data = [ {date: "Sep.08", name: "User1", count: 8}, {date: "Sep.08", name: "User2", count: 2}, {date: "Sep.09", name: "User2", count: 3}, {date: "Sep.09", name: "User3", count: 1}, {date: "Sep.12", name: "User1", count: 11}, {date: "Sep.13", name: "User1", count: 3}, {date: "Sep.13", name: "User2", count: 3}, {date: "Sep.14", name: "User2", count: 7}, ]
目标需求
- 每个用户名称对应结果对象中的一个数组;
- 每个数组需包含所有日期对应的数据,长度与
labels一致,若用户无对应日期的数据,则在该位置填充0。
预期结果
const result = { User1: [8,0,11,3,0], // Sep.09和Sep.14无数据,填充0 User2: [2,3,0,3,7], User3: [0,1,0,0,0], }
尝试的代码
我尝试用.reduce方法构建目标对象,但不知道如何将labels与累加器中的用户数据关联:
const Data = [ {date: "Sep.08", name: "User1", count: 8}, {date: "Sep.08", name: "User2", count: 2}, {date: "Sep.09", name: "User2", count: 3}, {date: "Sep.09", name: "User3", count: 1}, {date: "Sep.12", name: "User1", count: 11}, {date: "Sep.13", name: "User1", count: 3}, {date: "Sep.13", name: "User2", count: 3}, {date: "Sep.14", name: "User2", count: 7}, ] const labels = ["Sep.08", "Sep.09", "Sep.12", "Sep.13","Sep.14"] const groups = Data.reduce((acc, obj) => { if (!acc[obj.name]) { acc[obj.name] = []; } acc[obj.name].push(obj.count); return acc; }, {}); console.log(groups)
解决方案
可以分两步实现:先用reduce按用户分组,存储每个用户的日期-计数映射;再根据labels数组生成对应长度的结果数组,缺失日期填充0。
完整代码
const Data = [ {date: "Sep.08", name: "User1", count: 8}, {date: "Sep.08", name: "User2", count: 2}, {date: "Sep.09", name: "User2", count: 3}, {date: "Sep.09", name: "User3", count: 1}, {date: "Sep.12", name: "User1", count: 11}, {date: "Sep.13", name: "User1", count: 3}, {date: "Sep.13", name: "User2", count: 3}, {date: "Sep.14", name: "User2", count: 7}, ]; const labels = ["Sep.08", "Sep.09", "Sep.12", "Sep.13", "Sep.14"]; // 第一步:按用户分组,存储日期与count的映射 const userDateMap = Data.reduce((acc, item) => { if (!acc[item.name]) { acc[item.name] = {}; } acc[item.name][item.date] = item.count; return acc; }, {}); // 第二步:根据labels生成每个用户的结果数组 const result = Object.fromEntries( Object.entries(userDateMap).map(([user, dateCounts]) => { const counts = labels.map(date => dateCounts[date] || 0); return [user, counts]; }) ); console.log(result);
步骤解释
- 构建用户-日期映射:用
reduce遍历原始数据,为每个用户创建一个对象,键是日期,值是对应的count,这样能快速查找用户在指定日期的计数。 - 生成结果数组:遍历用户-日期映射的键值对,对每个用户,用
labels数组的每个日期去映射中查找,存在则取对应值,不存在则填0,最终生成符合长度要求的数组。 - 转换为目标对象:用
Object.fromEntries把键值对数组转换为最终的结果对象。
这样处理既保留了reduce的简洁性,又完美匹配了labels的顺序和缺失值填充需求。
内容的提问来源于stack exchange,提问作者CourtneyJ
相关产品推荐
相关产品推荐

