You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

修复要点说明

  1. 解决forEach报错:使用Object.entries(activitiesByYear)把年份对象转换成[年份字符串, 对应活动数组]的数组,即可用forEach遍历
  2. 修正周数获取逻辑:直接使用数据自带的actvityWeek字段,无需moment处理
  3. 修正属性名错误:统一使用数据中的avgSpeed字段,替换错误的average_speed
  4. 正确组装年份对象:将年份的字符串键转为数字后赋值给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:10:29