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

基于分数要求创建JavaScript排行榜对象的问题求助

问题:修正JavaScript排行榜排名计算函数

需求背景

我有两组JavaScript数据:

  • Users数组:存储用户ID与对应分数
  • minimumRequirements对象:定义各正式排名的最低分数要求(如第1名需≥100分,第2名≥50分,第3名≥10分)

排名规则:

  1. 用户按分数从高到低排序
  2. 仅满足对应排名最低分要求的用户,才能获得该正式排名(1、2、3名),且每个正式排名仅能分配给一个用户
  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;
  }

问题分析与修正方案

原函数问题点

  1. 遍历分数要求时错误累加currentPlace,导致排名逻辑混乱
  2. 未处理正式排名的唯一性(同一排名不能重复分配)
  3. 未正确计算未满足正式排名用户的起始排名

修正后的函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:30:01