如何将扁平CSV转换为按游戏-用户分组的嵌套JavaScript对象
分步实现按游戏-用户分组的计分板嵌套结构
需求回顾
你已将CSV数据转换为JavaScript数组scores,并获取了去重游戏列表,接下来需要实现按游戏分组,每个游戏下按用户分组,汇总用户总分并保留每场游戏的日期和得分,最终得到示例中的嵌套结构。
最佳实践分步实现
步骤1:用对象映射替代数组实现高效分组
之前用数组+findIndex的去重方法效率偏低,推荐用对象作为映射表——键为游戏名称,值为该游戏下的用户分组信息,查找和更新操作的时间复杂度为O(1),处理大量数据时更高效。
步骤2:遍历原始数据,填充嵌套分组结构
编写代码遍历scores数组,逐步构建目标结构:
// 初始化最终分组结果对象 const groupedScores = {}; // 遍历每一条得分记录 scores.forEach(score => { const { game, name, Date: date, score: points } = score; // 统一游戏名称大小写(避免"tennis"和"Tennis"被视为不同游戏) const normalizedGame = game.toLowerCase(); // 1. 若当前游戏未在分组中,初始化游戏层级结构 if (!groupedScores[normalizedGame]) { groupedScores[normalizedGame] = {}; } const gameGroup = groupedScores[normalizedGame]; // 2. 若当前用户未在该游戏分组中,初始化用户层级结构 if (!gameGroup[name]) { gameGroup[name] = { Total_score: 0, Played_games: [] }; } const userGroup = gameGroup[name]; // 3. 累加用户总分 userGroup.Total_score += points; // 4. 添加当前游戏的日期与得分记录 userGroup.Played_games.push({ date, points }); }); console.log(JSON.stringify(groupedScores, null, 2));
执行后groupedScores会生成如下嵌套结构:
{ "tennis": { "John": { "Total_score": 329, "Played_games": [ { "date": "31/12/2024", "points": 151 }, { "date": "25/12/2024", "points": 178 } ] }, "Klaas": { "Total_score": 188, "Played_games": [ { "date": "10/11/2024", "points": 188 } ] } }, "hockey": { "Piet": { "Total_score": 166, "Played_games": [ { "date": "01/12/2024", "points": 166 } ] } }, // 其他游戏分组... }
步骤3:格式化为示例的文本输出(可选)
如果需要转换成示例中的缩进文本格式,添加以下代码:
// 格式化分组结果为目标文本样式 function formatScoreboard(groupedData) { let result = ''; // 遍历每个游戏 Object.entries(groupedData).forEach(([game, users]) => { // 游戏名称首字母大写 result += `${game.charAt(0).toUpperCase() + game.slice(1)}:\n\n`; // 遍历每个用户 Object.entries(users).forEach(([user, data]) => { result += ` ${user}:\n\n`; result += ` Total_score: ${data.Total_score}\n`; result += ` Played_games:\n`; // 遍历每场游戏记录 data.Played_games.forEach(gameRecord => { result += ` ${gameRecord.date} ${gameRecord.points}\n`; }); result += '\n'; }); }); return result; } // 输出格式化后的文本 console.log(formatScoreboard(groupedScores));
关键优化点说明
- 对象映射分组:相比数组查找,对象键查找效率更高,数据量越大优势越明显。
- 解构赋值:提取
score对象属性,代码更简洁易读。 - 统一游戏名称大小写:避免因大小写差异导致的重复分组。
- 分步初始化结构:确保每个层级结构存在后再更新,避免运行时报错。
内容的提问来源于stack exchange,提问作者Bas van Ingen
相关产品推荐
相关产品推荐

