使用findIndex替代reduce按日期分组报表数组的问题求助(代码产生重复数据)
解决按日期分组报表数组的重复问题
我来帮你排查代码里的问题,然后给出正确的实现方案~
你的代码存在的几个问题:
- 索引处理错误:当
findIndex返回-1(即当前日期还没有分组项)时,你的slice(0, nodeIndex -1)相当于slice(0, -2),会返回空数组,然后你把新节点加进去,同时slice(nodeIndex +1)也是空数组,导致每次循环都会添加新节点,而不是同一日期只创建一个分组项。 - 没有合并用户数据:即使找到了已有的日期分组项,你直接用新节点替换了原有的项,而不是把当前用户的指标合并到已有项中,会导致之前的用户数据丢失,还会产生重复的日期项。
- 字段名错误:你创建的新节点用了
date字段,但原数据和期望输出里的字段是dateOfReport,这会导致输出结构不符合要求。
正确的实现方案(用reduce)
我们可以调整reduce的逻辑,核心是找到已有分组则合并用户,找不到则新增分组:
const groupedReports = reports.reduce((acc, dataItem) => { // 查找当前日期对应的分组项 const existingGroup = acc.find(item => item.dateOfReport === dataItem.dateOfReport); if (existingGroup) { // 如果存在该日期的分组,把当前用户的指标合并进去 existingGroup[dataItem.userId] = dataItem.userMetric; } else { // 如果不存在,创建新的分组项并加入数组 acc.push({ dateOfReport: dataItem.dateOfReport, [dataItem.userId]: dataItem.userMetric }); } return acc; }, []);
如果你想坚持用findIndex实现
也可以用findIndex定位索引,直接修改数组元素,性能会比find更高效一点(尤其是数据量大的时候):
const groupedReports = reports.reduce((acc, dataItem) => { const nodeIndex = acc.findIndex(item => item.dateOfReport === dataItem.dateOfReport); if (nodeIndex !== -1) { // 找到对应日期的分组,合并用户指标 acc[nodeIndex][dataItem.userId] = dataItem.userMetric; } else { // 未找到,新增分组项 acc.push({ dateOfReport: dataItem.dateOfReport, [dataItem.userId]: dataItem.userMetric }); } return acc; }, []);
验证输出
运行上面的代码后,得到的结果完全符合你的期望:
[ { dateOfReport: "11-01-2021", id1: { first_metric: 10, second_metric: 15 }, id2: { first_metric: 9, second_metric: 14 } }, { dateOfReport: "12-01-2021", id1: { first_metric: 11, second_metric: 14 }, id2: { first_metric: 16, second_metric: 19 } } ]
内容的提问来源于stack exchange,提问作者No Name
相关产品推荐
相关产品推荐

