1

我有以下数组:

$learners=array('Eliza'=87,  'Joe'=81, 'Anne'=69, 'Marley'=39, 'Teddy'=39, 'Jemma'=90, 'Sylvia'=87);

到目前为止,我已经能够将两个数组分开如下:

$tudents=array_keys($learners);
$scores=array_values($learners);

排名如下:

Student    Score    Position
Jemma       90          1
Sylvia      87          2
Eliza       87          2
Joe         81          4
Anne        69          5
Marley      39          7
Teddy       69          7

我想创建一个新数组,名称为键,位置为值,即

$positions=array('Jemma'=1, 'Sylvia'=2, 'Eliza'=2, 'Joe'=4, 'Anne'=5, 'Marley'=7, 'Teddy'=7);

这将允许我在脚本的任何位置回显任何名称和位置。我不确定如何进行。

如果分数有重复,排名就不是直截了当的。如果第 2 位出现平局,则跳过第 3 位。如果平局发生在分数的末尾,那么两个分数都将放在最后一个位置,并跳过前面的位置,在上面的示例中,位置 6 已被跳过,两个 39 占据位置 7。

任何帮助将不胜感激

4

3 回答 3

1
// Sort decending
arsort($data);

$vals  = array_values($data);
$last  = end($vals);   // The lowest score
$prev  = null;
$rank  = 0;

$positions = array();
foreach($data as $student => $score) {
    if ($score == $last) {
        // The score is the same as the lowest, the rank is set to last position
        $rank = count($data);
    } else if ($prev != $score) {
        // We only update if the score is not the same as prev
        $rank++;
    }  else if ($prev == $score) {
     // We matched on the key, replace any items with the
     // same score with the current rank 
     $matches = array_keys($positions, $score);
     foreach($matches as $key) {
       $positions[$key] = $rank;
     }
     $positions[$student] = $rank;
     // Now skip ahead to the next rank +1
     $rank = $rank + count($matches) + 1;
     continue;
    }
    $positions[$student] = $rank;
    $prev = $score; // Remember the previous score
}
var_dump($positions);
于 2013-11-02T00:01:41.810 回答
1

这是另一个解决方案:

首先按值排序( print_r 只是为了检查进度)。

arsort($learners);
print_r($learners);

然后做一个排名数组,但如果分数与前一个元素的分数相同,则不要提升排名。

$rank = $pos = 1;
$prev_score = current($learners);
foreach ($learners as $name => $score) {
    if ($score != $prev_score) {
        $rank = $pos;
    }
    $ranking[$name] = $rank;
    $prev_score = $score;
    $pos++;
}
print_r($ranking);

现在更正最后一个条目,任何与最后一个元素得分相同的元素都应该排在第 7 位。array_keys() 有一个很少使用的参数来搜索给定的值。

$low_score = end($learners);
$last_place = count($learners);
foreach (array_keys($learners, $low_score) as $name) {
    $ranking[$name] = $last_place;
}
print_r($ranking);

输出:

Array
(
    [Jemma] => 90
    [Sylvia] => 87
    [Eliza] => 87
    [Joe] => 81
    [Anne] => 69
    [Marley] => 39
    [Teddy] => 39
)
Array
(
    [Jemma] => 1
    [Sylvia] => 2
    [Eliza] => 2
    [Joe] => 4
    [Anne] => 5
    [Marley] => 6
    [Teddy] => 6
)
Array
(
    [Jemma] => 1
    [Sylvia] => 2
    [Eliza] => 2
    [Joe] => 4
    [Anne] => 5
    [Marley] => 7
    [Teddy] => 7
)
于 2013-11-01T23:30:15.040 回答
0

看起来像 PHP,对吧?

基本上遍历你的初始列表并将它们填充到一个使用名称作为键的新数组中(如果两个人有相同的名字,你会遇到麻烦,但我假设这是一个家庭作业,这不是问题? )

$sorted = array();
for ($i=0;$i<count($positions);$i++) {
 if (!isset($sorted[$positions[$i]["Student"]])) {
  $sorted[$positions[$i]["Student"]] = $positions[$i]["Score"];
 } else if ($sorted[$positions[$i]["Student"]]<$positions[$i]["Score"] {
  $sorted[$positions[$i]["Student"]] = $positions[$i]["Score"];
 }
}

您在这里所做的是创建一个数组,其中 KEY 是学生的姓名,并将您找到的第一个分数作为 VALUE。所以 $sorted["Jemma"] = 90。然后,如果您再次点击该名称,并且分数高于 $sorted["Jemma"] 的当前值,那么您将替换它。

之后,你运行一个 arsort($sorted) 来把它整理好。

于 2013-11-01T22:58:12.663 回答