如何将指定对象数组重新映射为目标结构的新数组?
解决数组转换问题:按用户聚合每日分数
我来帮你搞定这个数组转换的需求!你一开始想用map的思路方向是对的,但因为我们需要聚合分散在不同天数里的用户数据,单纯用map没法直接完成,得结合一个临时的映射对象来帮我们整理数据。下面是具体的实现方案和步骤解析:
完整代码实现
const initialData = [ { day: 1, values: [ { name: 'Roger', score: 90 }, { name: 'Kevin', score: 88 }, { name: 'Steve', score: 80 }, ], }, { day: 2, values: [ { name: 'Roger', score: 70 }, { name: 'Michael', score: 88 }, ], }, { day: 3, values: [ { name: 'Steve', score: 97 }, ], }, ]; // 1. 确定总天数(即每个用户scores数组的长度) const totalDays = initialData.length; // 2. 创建临时映射对象,存储每个用户的分数数组(初始全为null) const userScoreMap = {}; // 3. 初始化所有用户的分数数组 initialData.forEach(dayEntry => { dayEntry.values.forEach(user => { if (!userScoreMap[user.name]) { // 给新用户创建一个全null的数组,长度匹配总天数 userScoreMap[user.name] = Array(totalDays).fill(null); } }); }); // 4. 遍历每一天,填充对应用户的分数 initialData.forEach((dayEntry, dayIndex) => { dayEntry.values.forEach(user => { // dayIndex对应第几天(0是第1天,1是第2天...),把分数填到对应位置 userScoreMap[user.name][dayIndex] = user.score; }); }); // 5. 把映射对象转换成最终要求的数组格式 const result = Object.entries(userScoreMap).map(([name, scores]) => ({ name, scores })); console.log(result);
步骤解析
- 确定总天数:直接取
initialData的长度,因为数组里的每个元素对应一天,顺序正好是day1到day3,这样我们就知道每个用户的scores数组需要有多少个元素。 - 创建映射对象:用
userScoreMap来临时存储每个用户的分数数组,键是用户名,值是初始化好的全null数组,这样能快速定位到每个用户的分数位置。 - 初始化分数数组:遍历所有出现过的用户,给每个新用户创建对应长度的
null数组,确保没有遗漏任何用户。 - 填充分数数据:再次遍历每一天的数据,根据当前的索引(对应第几天),把用户的分数填充到映射对象里的对应位置。
- 转换为目标格式:用
Object.entries把映射对象的键值对拆出来,再映射成你需要的{ name, scores }对象结构,就得到最终结果了。
这个方法的优势是逻辑清晰,而且时间复杂度是O(n)(n是所有用户的总数量),效率很高。
内容的提问来源于stack exchange,提问作者ajbee
相关产品推荐
相关产品推荐

