React/ES6:如何用reduce处理workout日数据生成统计对象?
解决思路与代码实现
别慌,这个需求其实很好搞定!咱们只需要遍历原始数据的每个日期,对当日的训练列表做简单统计,就能得到你想要的结果。
核心逻辑
- 遍历原始对象的每个日期键,取出对应日期的训练数组
- 对每个训练数组计算三个关键值:
- 当日训练总数:直接取数组的长度即可
- 已完成训练数:筛选出
completed为true的训练项,统计其数量 - 总积分:累加所有已完成训练的
points值
完整代码示例
// 你的原始训练数据 const originalWorkouts = { "2019-03-02": [ { "id": 1, "workout_day": "2019-03-02", "title": "Swimming", "description": "", "completed": true, "points": 5 }, { "id": 2, "workout_day": "2019-03-02", "title": "Running", "description": "", "completed": false, "points": 0 }, { "id": 3, "workout_day": "2019-03-02", "title": "Rowing", "description": "", "completed": true, "points": 3 }, ], "2019-03-05": [ { "id": 4, "workout_day": "2019-03-05", "title": "Yoga", "completed": true, "points": 2 }, { "id": 5, "workout_day": "2019-03-05", "title": "Cycling", "completed": false, "points": 0 } ] }; // 生成统计结果的函数 const getWorkoutStats = (data) => { return Object.fromEntries( Object.entries(data).map(([date, workouts]) => { // 统计已完成训练的数量 const completedCount = workouts.filter(workout => workout.completed).length; // 计算已完成训练的总积分 const totalPoints = workouts.reduce((sum, workout) => { return workout.completed ? sum + workout.points : sum; }, 0); // 返回当前日期的统计对象 return [date, { workouts: workouts.length, workouts_completed: completedCount, total_points: totalPoints }]; }) ); }; // 执行函数得到最终结果 const workoutStats = getWorkoutStats(originalWorkouts); console.log(workoutStats);
代码细节解释
Object.entries(data):把原始对象转换成[日期, 训练数组]的键值对数组,方便我们逐个日期处理map:遍历每个日期的训练数据,计算出统计值后,返回新的键值对[日期, 统计对象]filter:筛选出所有已完成的训练项,用length得到已完成的数量reduce:从0开始累加积分,只对completed为true的训练项进行累加Object.fromEntries:把处理后的键值对数组重新转换成对象,完美匹配你需要的格式
运行这段代码后,你会得到如下结果:
{ "2019-03-02": { "workouts": 3, "workouts_completed": 2, "total_points": 8 }, "2019-03-05": { "workouts": 2, "workouts_completed": 1, "total_points": 2 } }
而且不管后续添加多少日期的训练数据,这个逻辑都能自动处理,完全不用修改代码~
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

