如何将日期键格式JSON转换为用户维度JSON结构?
如何将按日期分组的用户数据转换为按用户分组的格式?
我明白你现在卡在这个数据格式转换上了——把按日期分组的用户记录,转成每个用户作为一条记录、附带各日期空闲时长的结构对吧?之前用Object.values、Object.keys和map没达到预期,是因为这个场景需要聚合同一用户的多日期数据,光靠map的一对一转换不够,咱们用reduce来做分组聚合就搞定了。
先看具体的实现代码,我直接基于你的原始数据来写:
// 你的原始数据(注意外层数组取第一个元素,因为原始数据是数组包裹的单个对象) const originalData = [ { "2018-01-01": [ { "firstname": "mati", "lastname": "mati", "userid": null, "total_minutes": 0, "free_minutes": 480, "task_date": "2018-01-01" }, { "firstname": "andrzej", "lastname": "owsianka", "userid": null, "total_minutes": 0, "free_minutes": 480, "task_date": "2018-01-01" }, { "firstname": "asd", "lastname": "asd", "userid": null, "total_minutes": 0, "free_minutes": 480, "task_date": "2018-01-01" } ], "2018-01-02": [ { "firstname": "mati", "lastname": "mati", "userid": null, "total_minutes": "70", "task_date": "2018-01-02", "free_minutes": 410 }, { "firstname": "andrzej", "lastname": "owsianka", "userid": null, "total_minutes": "360", "task_date": "2018-01-02", "free_minutes": 120 }, { "firstname": "asd", "lastname": "asd", "userid": null, "total_minutes": "30", "task_date": "2018-01-02", "free_minutes": 450 } ], "2018-01-03": [ { "firstname": "mati", "lastname": "mati", "userid": null, "total_minutes": "0", "task_date": "2018-01-03", "free_minutes": 480 }, { "firstname": "andrzej", "lastname": "owsianka", "userid": null, "total_minutes": 0, "free_minutes": 480, "task_date": "2018-01-03" }, { "firstname": "asd", "lastname": "asd", "userid": null, "total_minutes": 0, "free_minutes": 480, "task_date": "2018-01-03" } ] } ][0]; // 步骤1:提取所有日期 const allDates = Object.keys(originalData); // 步骤2:把所有日期的用户记录合并成一个数组 const allUserRecords = allDates.flatMap(date => originalData[date]); // 步骤3:用reduce按用户分组,聚合各日期的free_minutes const groupedUsers = allUserRecords.reduce((userMap, record) => { // 因为userid是null,用firstname+lastname作为唯一标识键 const userKey = `${record.firstname}-${record.lastname}`; // 如果用户还没在map里,先初始化基础信息 if (!userMap[userKey]) { userMap[userKey] = { firstname: record.firstname, lastname: record.lastname }; } // 给当前用户添加对应日期的空闲时长 userMap[userKey][record.task_date] = record.free_minutes; return userMap; }, {}); // 步骤4:把map转成你要的数组格式 const finalResult = Object.values(groupedUsers); console.log(finalResult);
运行这段代码后,得到的结果就是你期望的结构(注意2018-01-02的数值会和原始数据一致,比如andrzej的是120,mati是410,asd是450,和你示例里的全480应该是笔误)。
为什么之前的方法没成功?
你之前尝试的map是对数组的每个元素做一对一转换,但这里需要把同一用户的多条记录合并成一条,这种聚合场景用reduce更合适——它可以帮我们逐步构建一个用户映射表,把每个日期的记录对应到用户身上。
额外说明
如果之后userid不为null了,把userKey换成record.userid就可以,这样分组会更准确。
内容的提问来源于stack exchange,提问作者Adrian Miesikowski
相关产品推荐
相关产品推荐

