如何按name合并JavaScript对象数组中的data数组?
如何合并JavaScript对象数组中相同name的data数组(按日期聚合数值)
我来帮你修正代码并实现需求,先分析下原代码的问题,再给出正确的实现方案:
原代码的核心问题
你的reduce逻辑存在几个关键错误:
acc.find((a, index) => a.data[index][0] === d.data[index][0])中的index是acc数组的索引,不是data子数组的索引,这导致你错误地拿不同层级的索引做匹配,完全不符合按name分组的需求dataNew = a.data[index][1] + d.data[index][1]中的a和index没有在当前作用域定义,会直接抛出引用错误- 整体逻辑没有围绕
name做分组,而是错误地尝试匹配不同对象的data子项索引,无法实现相同name下的data合并
正确实现代码
以下是能满足你需求的代码,核心思路是先按name分组,再对相同日期的数值做累加:
const result = Object.values(norm.series.reduce((acc, currentItem) => { // 按name作为分组键 const groupKey = currentItem.name; if (!acc[groupKey]) { // 首次遇到该name,初始化分组数据 acc[groupKey] = { id: currentItem.id, // 保留第一个出现的id name: currentItem.name, dataMap: {} // 用对象存储日期与数值的映射,方便快速累加 }; // 将当前data存入映射 currentItem.data.forEach(([date, value]) => { acc[groupKey].dataMap[date] = value; }); } else { // 已有该name分组,累加对应日期的数值 currentItem.data.forEach(([date, value]) => { if (acc[groupKey].dataMap[date]) { acc[groupKey].dataMap[date] += value; } else { acc[groupKey].dataMap[date] = value; } }); } return acc; }, {})).map(group => { // 将dataMap转换回[[date, value]]的数组格式 return { ...group, data: Object.entries(group.dataMap) }; });
代码工作原理
- 分组阶段:用
reduce构建一个以name为键的临时对象,每个键对应的值包含第一个出现的id、name,以及一个dataMap(用来快速查找和累加日期对应的数值) - 累加阶段:遍历每个对象的
data数组,对相同日期的数值做累加,不同日期则直接添加到dataMap中 - 格式转换阶段:用
Object.values取出所有分组数据,再将dataMap转换回你需要的[[date, value]]数组格式
用你提供的输入数据测试,这段代码会输出你期望的结果:
Bingo的data中date1的数值会累加为2.0,其他日期保留,id使用第一个出现的qah01Combo和Sango因name唯一,会直接保留原数据
内容的提问来源于stack exchange,提问作者Malika SN
相关产品推荐
相关产品推荐

