教学系统学生成绩排名功能优化:实现同分学生分配相同排名
Let's adjust your function so students with identical average scores get the same rank. The core issue with your current code is that it increments the rank by 1 for every student, regardless of their score. Here's the modified version with explanations:
Modified Code
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); $gtotal = $gtotal + $totalMarks; $mGTotal[$idd] = $gtotal; if ($totalMarks != 0) { $totSubjects = $totSubjects + 1; } 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 (! is_nan($val)) { $nums[$dd] = $val; } } arsort($nums); // --- Updated ranking logic --- $previous_avg = null; $current_rank = 1; $position_index = 1; foreach ($nums as $kk => $av) { // Only update rank when the current score is different from the previous if ($previous_avg !== null && $av != $previous_avg) { $current_rank = $position_index; } // Return the rank if we found the target student if ($student_id == $mId[$kk]) { return $current_rank; } $previous_avg = $av; $position_index++; } // Fallback if the student isn't found in the list return null; }
Key Changes Explained
- Track Previous Score: We added
$previous_avgto compare the current student's average with the last one processed. This lets us detect when scores are the same and keep the rank consistent. - Separate Rank and Position:
$current_rankis the actual rank we'll return (shared for identical scores).$position_indexcounts every student processed. When a new score is detected, we set$current_rankto$position_index—this ensures ranks skip ahead for students after a group of high-scorers (e.g., 3 students with rank 1 will make the next student rank 4, which follows standard competitive ranking rules).
- Cleaned Unused Code: The inner loop over
$totalSubMarksin the ranking phase was redundant (it didn't use the$totalMarksvalue), so we removed it to boost performance and simplify the code.
Alternative Ranking (No Skipping)
If you prefer that ranks don't skip after a group of students with the same score (e.g., 3 students rank 1, next student ranks 2), use this simplified ranking logic instead:
// Alternative ranking logic $previous_avg = null; $current_rank = 1; foreach ($nums as $kk => $av) { if ($previous_avg !== null && $av != $previous_avg) { $current_rank++; } if ($student_id == $mId[$kk]) { return $current_rank; } $previous_avg = $av; }
Pick the version that matches your school's ranking policy!
内容的提问来源于stack exchange,提问作者MaryUghojor
相关产品推荐
相关产品推荐

