groupBy保留单个条目:评分系统同分排名分组结果异常问题
解决评分系统同分同名次的问题
嘿,我完全懂你遇到的困扰——用groupBy处理同分排名的时候,它直接把同分数的条目合并成了一组,导致你丢失了原始的每个条目,但咱们要的是保留所有提交条目,同时给同分的标记相同名次,对吧?
为什么groupBy不适用?
groupBy的核心作用是将相同键值的元素归为一个集合,所以它会把两个100分的条目合并成一个组,这和咱们需要保留每个原始条目的需求不符,所以得换个思路处理。
正确的实现步骤
咱们可以先对条目按分数降序排序,然后遍历的时候跟踪当前分数和名次,给每个条目单独标记名次:
1. 先对提交列表按分数降序排序
假设你的$submissions是包含分数的数组,先用usort排序:
usort($submissions, function($a, $b) { // 按分数从高到低排序 return $b['score'] <=> $a['score']; });
2. 遍历排序后的数组,计算每个条目的名次
通过跟踪上一个分数和当前名次,给同分的条目赋予相同名次:
$currentRank = 1; $previousScore = null; $sameScoreCount = 0; foreach ($submissions as &$sub) { if ($sub['score'] !== $previousScore) { // 遇到新分数,更新名次(加上之前同分的数量) $currentRank += $sameScoreCount; $sameScoreCount = 1; $previousScore = $sub['score']; } else { // 同分,名次不变,计数加1 $sameScoreCount++; } // 给当前条目赋值名次 $sub['rank'] = $currentRank; } unset($sub); // 释放引用,避免后续数组操作出问题
效果示例
处理后你的$submissions会保留所有3个条目,每个条目都带有正确的名次:
- 第一个100分条目:
rank = 1 - 第二个100分条目:
rank = 1 - 第三个90分条目:
rank = 2
这样就完美实现了同分同名次,同时保留所有原始条目的需求啦!
内容的提问来源于stack exchange,提问作者Packy
相关产品推荐
相关产品推荐

