首页 > 解决方案 > 为相同分数的学生分配相同的排名

问题描述

我正在根据学生的分数为他们分配排名,但我遇到了一个问题,如果两个或更多学生的分数相同,他们将获得不同的排名。

EG John、Rita 和 Mary 得分 76。John 排名第一,Rita 排名第二,Mary 排名第三。

  1. 约翰 ==> 76
  2. 丽塔 ==> 76
  3. 玛丽 ==> 76
  4. 布基 ==> 74

我希望他们中的三个排名第一。

  1. 约翰 ==> 76
  2. 丽塔 ==> 76
  3. 玛丽 ==> 76
  4. 布基 ==> 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;
    }
}

标签: phpcodeigniter

解决方案


正如 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. 应该不会太难。在这种情况下,只需添加评论,以便我可以更改我的答案,它实际上是正确的。

希望有帮助!


推荐阅读