基于分数要求创建JavaScript排行榜对象的问题求助
问题:修正JavaScript排行榜排名计算函数
需求背景
我有两组JavaScript数据:
- Users数组:存储用户ID与对应分数
- minimumRequirements对象:定义各正式排名的最低分数要求(如第1名需≥100分,第2名≥50分,第3名≥10分)
排名规则:
- 用户按分数从高到低排序
- 仅满足对应排名最低分要求的用户,才能获得该正式排名(1、2、3名),且每个正式排名仅能分配给一个用户
- 未满足任何正式排名要求,或对应排名已被占用的用户,排名从「正式排名总数+1」开始依次递增
示例验证
示例1(Group1)
输入用户数据:
[ { userId: 'id1', score: 3 }, { userId: 'id2', score: 2 }, { userId: 'id3', score: 1 } ]
预期输出:
[ { userId: 'id1', place: 4 }, { userId: 'id2', place: 5 }, { userId: 'id3', place: 6 } ]
示例2(Group2)
输入用户数据:
[ { userId: 'id1', score: 55 }, { userId: 'id2', score: 30 }, { userId: 'id3', score: 52 }, { userId: 'id4', score: 10 }, { userId: 'id5', score: 1 } ]
预期输出:
[ { userId: 'id1', place: 2 }, { userId: 'id3', place: 3 }, { userId: 'id2', place: 4 }, { userId: 'id4', place: 5 }, { userId: 'id5', place: 6 } ]
现有问题代码
我编写的函数无法正确筛选符合排名要求的用户,导致排名计数错误:
function getLeaderboard(users, minScores) { let leaderboard = []; let formattedMinScores = Object.values(minScores); const sortedUsers = users.sort((a, b) => b.score - a.score); loop1: for (let i = 0; i < sortedUsers.length; i++) { let currentPlace = i + 1; loop2: for (let j = 0; j < formattedMinScores.length; j++) { ++currentPlace; if (sortedUsers[i].score >= formattedMinScores[j]) { currentPlace = j + 1; break loop2; } } leaderboard.push({ place: currentPlace, userId: sortedUsers[i].userId }); } console.log(leaderboard); return leaderboard; }
问题分析与修正方案
原函数问题点
- 遍历分数要求时错误累加
currentPlace,导致排名逻辑混乱 - 未处理正式排名的唯一性(同一排名不能重复分配)
- 未正确计算未满足正式排名用户的起始排名
修正后的函数
function getLeaderboard(users, minScores) { // 将最低分数要求转换为含排名的数组,按排名1、2、3顺序排列 const rankRequirements = Object.entries(minScores) .map(([key, score]) => { const rank = parseInt(key.match(/(\d+)/)[1]); return { rank, minScore: score }; }) .sort((a, b) => a.rank - b.rank); const totalFormalRanks = rankRequirements.length; // 深拷贝用户数组并按分数降序排序,避免修改原数据 const sortedUsers = [...users].sort((a, b) => b.score - a.score); const usedRanks = new Set(); // 记录已占用的正式排名 let nextNonFormalRank = totalFormalRanks + 1; // 非正式排名起始值 return sortedUsers.map(user => { // 寻找用户能获得的最高可用正式排名 for (const req of rankRequirements) { if (user.score >= req.minScore && !usedRanks.has(req.rank)) { usedRanks.add(req.rank); return { userId: user.userId, place: req.rank }; } } // 无可用正式排名,分配连续的后续排名 return { userId: user.userId, place: nextNonFormalRank++ }; }); }
验证测试
运行示例1代码:
const group1Users = [ { userId: 'id1', score: 3 }, { userId: 'id2', score: 2 }, { userId: 'id3', score: 1 } ]; const minScores = { firstPlaceMinScore: 100, secondPlaceMinScore: 50, thirdPlaceMinScore: 10 }; console.log(getLeaderboard(group1Users, minScores));
将输出符合预期的place:4、5、6。
运行示例2代码:
const group2Users = [ { userId: 'id1', score: 55 }, { userId: 'id2', score: 30 }, { userId: 'id3', score: 52 }, { userId: 'id4', score: 10 }, { userId: 'id5', score: 1 } ]; console.log(getLeaderboard(group2Users, minScores));
将输出符合预期的place:2、3、4、5、6。
内容的提问来源于stack exchange,提问作者denistepp
相关产品推荐
相关产品推荐

