php - 为相同分数的学生分配相同的排名
问题描述
我正在根据学生的分数为他们分配排名,但我遇到了一个问题,如果两个或更多学生的分数相同,他们将获得不同的排名。
EG John、Rita 和 Mary 得分 76。John 排名第一,Rita 排名第二,Mary 排名第三。
- 约翰 ==> 76
- 丽塔 ==> 76
- 玛丽 ==> 76
- 布基 ==> 74
我希望他们中的三个排名第一。
- 约翰 ==> 76
- 丽塔 ==> 76
- 玛丽 ==> 76
- 布基 ==> 74
public function getStudentpositionOnlyClass($student_id, $class_id, $terms)
{
$array_product = array();
if ($class_id == 22 || $class_id == 23) {
if ($terms == 'f') {
$totField = 'ft_tot_score';
$table = 'ftscores_rn';
} elseif ($terms == 'm') {
$totField = 'mt_tot_score';
$table = 'mtscores_rn';
} elseif ($terms == 's') {
$totField = 'tot_score';
$table = 'scores_rn';
} elseif ($terms == 'h') {
$totField = 'h_tot_score';
$table = 'hscores_rn';
}
} else {
if ($terms == 'f') {
$totField = 'ft_tot_score';
$table = 'ftscores_primary';
} elseif ($terms == 'm') {
$totField = 'mt_tot_score';
$table = 'mtscores_primary';
} elseif ($terms == 's') {
$totField = 'tot_score';
$table = 'scores_primary';
} elseif ($terms == 'h') {
$totField = 'h_tot_score';
$table = 'hscores_primary';
}
}
$fail = 0;
$pass = 0;
$resultlist = $this->student_model->fullSearchByClass($class_id);
foreach ($resultlist->result_array() as $key => $stdName) {
$idd = $key + 1;
$mId[$idd] = $stdName['pstudent_id'];
$totalSubMarks = $this->db->query(
"SELECT mts.subject_id
FROM " . $table . " mts
LEFT JOIN subjects sub ON(sub.id=mts.subject_id)
WHERE class_id=" . $class_id .
" AND mts.subject_id IS NOT NULL
GROUP BY mts.subject_id ORDER BY sub.name");
$gtotal = 0;
$totSubjects = 0;
foreach ($totalSubMarks->result_array() as $tmrow) {
$totalMarks = $this->student_model->getTotalMarksForStudnets($tmrow['subject_id'],
$stdName['pstudent_id'], $table, $totField);
// //// set mtotalmark
$gtotal = $gtotal + $totalMarks;
// //// set mgtotal
$mGTotal[$idd] = $gtotal;
if ($totalMarks != 0) {
$totSubjects = $totSubjects + 1;
}
// //// set mAvg
if ($totSubjects != 0) {
$mAvg[$idd] = round($gtotal / $totSubjects, 1);
} else {
$mAvg[$idd] = 0;
}
}
// /////////
if ($totSubjects != 0) {
$percentage = ($gtotal / $totSubjects);
}
if ($percentage >= 0 && $percentage <= 39.99) {
$fail = $fail + 1;
} else {
$pass = $pass + 1;
}
}
foreach ($mAvg as $dd => $val) {
// if pure numbers store in nums array
if (! is_nan($val)) {
$nums[$dd] = $val;
}
}
arsort($nums);
$id = 1;
foreach ($nums as $kk => $av) {
foreach ($totalSubMarks->result_array() as $tmrow) {
$totalMarks = $this->student_model->getTotalMarksForStudnets($tmrow['subject_id'], $mId[$kk], $table,
$totField);
}
if ($student_id == $mId[$kk]) {
return $id;
}
// $array_product['student'.$mId[$kk]]= $id;
$id += 1;
}
}
解决方案
正如 mickmackusa 在他的评论中所说,您必须记住以前的分数,并且只有在分数发生变化时才增加排名。由于您已经订购了结果,我们可以假设 2 次迭代之间的分数变化总是减少。
您的变量名称非常不直观。所以也许我的代码更改在错误的地方,但你应该理解这个概念。我想这$totSubjects
就是这个分数。
尽量不要过多地缩短变量的名称,因为您没有任何好处,反而会丢失关于它是什么的重要信息。如果不清楚变量的含义,至少注释变量赋值。
像这样改变你的循环:
$previousScore = null; // added THIS
foreach ($totalSubMarks->result_array() as $tmrow) {
$totalMarks = $this->student_model->getTotalMarksForStudnets($tmrow['subject_id'],
$stdName['pstudent_id'], $table, $totField);
// set mtotalmark
$gtotal = $gtotal + $totalMarks;
// set mgtotal
$mGTotal[$idd] = $gtotal;
if ($totalMarks != 0) {
if($previousScore != $totalMarks) { // added THIS
$totSubjects = $totSubjects + 1;
} else { // added THIS
$totSubjects = $totSubjects; // keep rank without incrementing
}
}
$previousScore = $totalMarks; // added THIS
// set mAvg
if ($totSubjects != 0) {
$mAvg[$idd] = round($gtotal / $totSubjects, 1);
} else {
$mAvg[$idd] = 0;
}
}
如果 $gtotal
或任何其他神秘变量;) 持有分数,然后尝试将我给定的代码更改修改为$gtotal
. 应该不会太难。在这种情况下,只需添加评论,以便我可以更改我的答案,它实际上是正确的。
希望有帮助!
推荐阅读
- tensorflow - 在 TPU 上训练时如何在 tf keras 中保存模型权重?
- javascript - 如何在函数中导出 javascript 中的变量?
- node.js - Nestjs 项目无法启动,因为它读取了其模块之外的文件
- xamarin - Xamarin 唤醒锁
- javascript - Google-Maps-React 与 TypeScript。参数错误
- java - 有没有办法在 Junit5 中的另一个方法中模拟私有方法调用
- elasticsearch - 在 Elasticsearch 中,我如何检索按销售商店分组的产品?
- apache-spark - 从 PySpark 数组中删除 NULL 项
- ios - Flutter:Pod install 突然报错
- python-3.x - os.environ 从无引发 keyerror(key)