为学生分配职位,PHP

Assigning Positions to Students, PHP

我在PHP 脚本方面还是个新手。

我有一个数组

$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);

从关联数组中,键是学生的考试编号,值是学生的分数。然后我使用 2 inbult PHP 函数 array_keys 和 array_values 将考试编号与分数分开。

$exam_nos=(array_keys($students)); 
$marks=(array_values($students));

然后我通过下面的代码传递了 $marks 数组:

 $i=0;
$occurrences = array_count_values($marks);
$marks = array_unique($marks);
echo '<table border="1">';
foreach($marks as $grade) {
  if($grade == end($marks))$i += $occurrences[$grade]-1;
  echo str_repeat('<tr><td>'.$grade.': '.($i+1).'</td></tr>',$occurrences[$grade]);
  $i += $occurrences[$grade];
}
echo '</table><br />';

输出:

 94: 1
 94: 1
 94: 1
 91: 4
 89: 5
 83: 6
 65: 7
 41: 8
 38: 9
 37: 11
 37: 11

这更接近我想要的;对分数进行排名,如果遇到平局,则跳过 1 个或多个位置,发生在末尾的位置,末尾的项目被分配的位置等于排名项目的总数。但是,如果可以在不将 Array 分成 2 ... 问题: (1) 我正在扯我的头发,如何从 $student 数组中得到类似的东西:

Exam No Score Position
 1201     94      1
 1210     94      1
 1203     94      1
 1200     91      4
 1205     89      5
 1209     83      6
 1206     65      7
 1202     41      8
 1207     38      9
 1204     37      11
 1208     37      11

(2) 我希望能够通过考试编号挑选任何学生,并能够回应或打印出她的位置,例如

学生1207是编号9

我想我需要捕获变量中的位置,但如何捕获它们?嗯,我不知道!

专家们能否在这里帮助我更好的方法来实现我的 2 个目标(请参阅问题 1 和 2)?我会尝试任何有助于我解决 'metal blockage' 我遇到的问题的建议。

我会使用自定义对象来单独处理学生并将它们存储在数组中。

$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);
arsort($students); // Sort the array so the higher scores are on top.

$newStudents = array();
$pos = 0;
$count = 0;
$holder = -1; // Assuming no negative scores.
foreach($students as $k=>$v){
    $count++; // increment real counter
    if($v < $holder || $holder == -1){
        $holder = $v;
        $pos = $count;
    }

    $newStudents[] = makeStudent($pos, $v, $k);
    // If you want the exam # as the array key.
    // $newStudents[$k] = $student;
}

$newStudents = fixLast($newStudents);

// outputs
print_r($newStudents);

foreach($newStudents as $v){
   echo "position : " . $v->position . "<br>";
   echo "score : " . $v->score . "<br>";
   echo "exam : " . $v->exam . "<br>";
}


function makeStudent($pos, $score,$examNo){
    $student = new stdClass(); // You could make a custom, but keeping it simple
    $student->position = $pos;
    $student->score = $score;
    $student->exam = $examNo;

    return $student;
}

function fixLast($students){
    $length = count($students) -1;
    $count = 0;
    $i = $length;
    while($students[$i]->position == $students[--$i]->position){
        $count++;
    }

    for($i = 0; $i <= $count; $i++){
        $students[$length - $i]->position = $students[$length - $i]->position + $count;
    }
    return $students;
}

如果您要从数据库中提取学生(在评论中提到),您可以直接使用 SQL.

以所需的格式检索它们

但是,我假设这不是一个选项。你可以这样做:

$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);
arsort($students);// It orders high to low by value. You could avoid this with a simple ORDER BY clause in SQL.

$result = array();
$pos = $real_pos = 0;
$prev_score = -1;
foreach ($students as $exam_n => $score) {
    $real_pos += 1;// Natural position.
    $pos = ($prev_score != $score) ? $real_pos : $pos;// If I have same score, I have same position in ranking, otherwise, natural position.
    $result[$exam_n] = array(
                     "score" => $score, 
                     "position" => $pos, 
                     "exam_no" => $exam_n
                     );
    $prev_score = $score;// update last score.
}

$desired = 1207;
print_r($result);
echo "Student " . $result[$desired]["exam_no"] . ", position: " . $result[$desired]["position"] . " and score: ". $result[$desired]["score"];

希望对您有所帮助。