为学生分配职位,PHP

时间:2015-02-07 17:58:52

标签: php arrays loops

我仍然是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个或多个位置,在结束时发生位置,最后的项目被分配相当于排序项目总数的位置。但是,如果可以在不将阵列分成2的情况下完成,那将会非常有用... 问题: (1)我正在拉我的头发,从$学生阵列我可以得到类似的东西:

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)?我将尝试任何可以帮助我解决我遇到的“金属堵塞”的建议。

2 个答案:

答案 0 :(得分:2)

如果您从数据库中提取学生(在评论中提到),您可以使用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"];

希望它对你有所帮助。

答案 1 :(得分:1)

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

$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;
}