JavaScript数组按属性分组并按另一属性汇总的问题排查
问题分析与修复方案
首先,报错activitiesByYear.forEach is not a function的核心原因:你的groupBy函数返回的是键为年份、值为对应活动数组的对象,而非数组,对象没有forEach方法,这是首要解决的问题。
除此之外,代码里还有几处逻辑错误需要修正:
- 错误调用
moment(value.actvityDate).week(),但数据中不存在actvityDate属性,应直接使用value.actvityWeek - 属性名拼写错误:将数据中的
avgSpeed误写为average_speed - 组装年份对象时,错误地把活动数组赋值给
year字段,应使用年份的键值
以下是修复后的完整代码:
const activities = [ { "id": 1, "actvityYear": 2015, "actvityWeek": 45, "name": "One", "avgSpeed": 1200, "distance": 2 }, { "id": 2, "actvityYear": 2015, "actvityWeek": 45, "name": "Two", "avgSpeed": 1403, "distance": 6 }, { "id": 3, "actvityYear": 2015, "actvityWeek": 46, "name": "Three", "avgSpeed": 1700, "distance": 7 }, { "id": 4, "actvityYear": 2015, "actvityWeek": 47, "name": "Four", "avgSpeed": 600, "distance": 12 }, { "id": 5, "actvityYear": 2015, "actvityWeek": 47, "name": "Five", "avgSpeed": 300, "distance": 4 }, { "id": 6, "actvityYear": 2016, "actvityWeek": 2, "name": "Six", "avgSpeed": 1800, "distance": 15 } ]; function groupBy(objectArray, property) { return objectArray.reduce((acc, obj) => { const key = obj[property]; if (!acc[key]) { acc[key] = []; } acc[key].push(obj); return acc; }, {}); } const activitiesByYear = groupBy(activities, 'actvityYear'); let years = []; // 将年份对象转为[key, value]数组,实现遍历 Object.entries(activitiesByYear).forEach(([yearKey, yearActivities]) => { let weeks = []; const weekMap = yearActivities.reduce((result, activity) => { const week = activity.actvityWeek; if (!result[week]) { result[week] = { week: week, totalDistance: 0, maxAvgSpeed: activity.avgSpeed }; weeks.push(result[week]); } // 累加总距离 result[week].totalDistance += activity.distance; // 更新最大平均速度 if (activity.avgSpeed > result[week].maxAvgSpeed) { result[week].maxAvgSpeed = activity.avgSpeed; } return result; }, {}); years.push({ "year": Number(yearKey), // 将字符串年份转为数字 "weeks": weeks }); }); console.log(years);
修复要点说明
- 解决forEach报错:使用
Object.entries(activitiesByYear)把年份对象转换成[年份字符串, 对应活动数组]的数组,即可用forEach遍历 - 修正周数获取逻辑:直接使用数据自带的
actvityWeek字段,无需moment处理 - 修正属性名错误:统一使用数据中的
avgSpeed字段,替换错误的average_speed - 正确组装年份对象:将年份的字符串键转为数字后赋值给
year字段,活动数组作为yearActivities处理
输出结果
运行后会得到你预期的结构:
[ { "year": 2015, "weeks": [ { "week": 45, "totalDistance": 8, "maxAvgSpeed": 1403 }, { "week": 46, "totalDistance": 7, "maxAvgSpeed": 1700 }, { "week": 47, "totalDistance": 16, "maxAvgSpeed": 600 } ] }, { "year": 2016, "weeks": [ { "week": 2, "totalDistance": 15, "maxAvgSpeed": 1800 } ] } ]
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

