Php 如何使用重复值对数组值进行排序,并在出现平局时跳过某些位置?

Php 如何使用重复值对数组值进行排序,并在出现平局时跳过某些位置?,php,mysql,Php,Mysql,我正在制作一个数据库,用来处理大学生的考试成绩。基本上,我是从MySq数据库中提取记录,在任何给定的时间调用一个类。我想对学生进行排名,表现最好的学生排在第一位。 这是一个例子 Marks: 37, 92, 84, 83, 84, 65, 41, 38, 38, 84. 所以我想将mysql数据捕获为单个数组。一旦我有了数组中的数据,我应该给每个学生分配一个位置,比如1/10(数字1,92分)、4/10等。现在的问题是,如果出现平局,那么下一个分数跳过一个位置,如果一个位置有3分,那么下一

我正在制作一个数据库,用来处理大学生的考试成绩。基本上,我是从MySq数据库中提取记录,在任何给定的时间调用一个类。我想对学生进行排名,表现最好的学生排在第一位。
这是一个例子

Marks: 37, 92, 84, 83, 84, 65, 41, 38, 38, 84.  
所以我想将mysql数据捕获为单个数组。一旦我有了数组中的数据,我应该给每个学生分配一个位置,比如1/10(数字1,92分)、4/10等。现在的问题是,如果出现平局,那么下一个分数跳过一个位置,如果一个位置有3分,那么下一个分数跳过2个位置。因此,上述分数将按如下顺序排列:

92 - 1
84 - 2,
84 - 2,
84 - 2,
83 - 5,
65 - 6,
41 - 7,
38 - 8,
38 - 8 ,
37 - 10
分级系统要求保持职位数量(如果愿意,请保持职级),因此,由于职位3、4、5和9没有任何占用者,我们最终在该类别中获得了10个职位。(填写每个数字的备选方案只会给我们8个职位!)

是否有可能(人性上可能/php可能)使用php对上面的分数进行排序,以便它能够处理可能的联系,例如在一个位置上有4个分数?遗憾的是,我无法想出一个函数来实现这一点。我需要一个PHP函数(或其他什么…PHP),它将获取一个数组并生成如上所述的排名

任何帮助都将不胜感激,尽管我想我可能要求太多了。如果可以对MySQL查询数据执行此操作,而无需将其放入数组中,那么这也将非常有用

$scores=数组(92,84,84,84,83,65,41,38,38,37);
$scores = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37);
$ranks = array(1);
for ($i = 1; $i < count($scores); $i++)
{
    if ($scores[$i] != $scores[$i-1])
        $ranks[$i] = $i + 1;
    else
        $ranks[$i] = $ranks[$i-1];
}
print_r($ranks);
$ranks=数组(1); 对于($i=1;$i
我假设等级已经按数据库排序,否则使用
排序($grades)

代码:

$grades = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37);
$occurrences = array_count_values($grades);
$grades = array_unique($grades);
foreach($grades as $grade) {
    echo str_repeat($grade .' - '.($i+1).'<br>',$occurrences[$grade]);
    $i += $occurrences[$grade];
}
92 - 1
84 - 2
84 - 2
84 - 2
83 - 5
65 - 6
41 - 7
38 - 8
38 - 8
37 - 10
编辑(对下面讨论的回应)

显然,如果平局发生在最低分数,
所有最低分数的排名应等于总分数。

代码:


我需要一张价值地图来排名。这种方法对原始问题也可能更有效

public static function getGrades($grades)
{
    $occurrences = array_count_values($grades);
    krsort($occurrences);

    $position = 1;
    foreach ($occurrences as $score => $count) {
        $occurrences[$score] = $position;
        $position += $count;

    }

    return $occurrences;
}
如果您打印$r,您将获得

Array
(
    [92] => 1
    [84] => 2
    [83] => 5
    [65] => 6
    [41] => 7
    [38] => 8
    [37] => 10
)

基于原来的答案,所以谢谢

@Bululu作为stuken.yuri代码的补充,我要指出的是,您可以从已经排序的数据库中获取数据,因此您不必通过php函数对其进行排序。我可以通过在查询中添加一些参数从mysql中获取排序。你是说有可能将数据操纵到我问题中描述的程度吗?在平局时跳过一些位置?这是一个我认为不能通过在查询中按DESC或ASC添加order来实现的要求。如果您能详细说明我如何使用查询实现如此高的排名,我将非常高兴。yuri,非常感谢您,您的解决方案也解决了问题。在平局结束之前,效果非常好。在这种情况下,分配给最后分数(平局的分数)的位置将不等于总分数。在上面的输出中,您将看到分数37位于第10位,这是不可分割的,因为它是最低的分数,恰好是学生总数。但是,如果我们在37分(最低分数)而不是38分打成平局,那么最后两个分数将被分配到第9位,而不是第10位。我想需要一个条件来检查平局是否涉及最低分数,我正在尝试添加这样的条件,比如我们有以下数组:
$grades=array(92,84,84,83,65,41,38,37,37)
两个
37
都显示在结果中,如
37-9
,这是正确的,因为第一个
37
实际上位于第九个位置。总之:当平局发生在最低等级时,每个最低等级的排名等于最低等级第一次出现的排名。在这种情况下,
9
。对吗?我认为你的代码应该解决这个问题。确保最后的分数与参加考试的学生人数相等的理由有些缺陷。如果平局发生在比赛结束以外的任何地方,最低分数将等于学生总数。如果这是在最后一个不可能发生的情况,并且IU同意tyou bec的观点,因为如果第二个最低的得分手被定位在比如说,9,那么下一个得分手应该正确地获得下一个位置,因为在那之后没有得分。同时非常感谢你的回答,你是个天才!添加了额外的代码,希望我理解正确:)太棒了!非常感谢你。我几乎认为设计这个系统的人可能弄错了,所以我搜索了一下,找到了一个powerpoint演示文稿,解释了学生的排名,它还说,得分最低的人必须把参加考试的学生人数作为自己的位置,而不管分数有多高。所以我想这个新的解决方案是可以被普遍接受的。再次感谢你。我希望我有必要的声誉来投票支持你的答案。
public static function getGrades($grades)
{
    $occurrences = array_count_values($grades);
    krsort($occurrences);

    $position = 1;
    foreach ($occurrences as $score => $count) {
        $occurrences[$score] = $position;
        $position += $count;

    }

    return $occurrences;
}
Array
(
    [92] => 1
    [84] => 2
    [83] => 5
    [65] => 6
    [41] => 7
    [38] => 8
    [37] => 10
)