如何在没有关系的情况下对数组值进行排名?

How can I do a ranking on array values without ties?

我有一个代表排名或位置的数组(比如在游戏或竞赛中):

rank = [1,3,2,1]

我希望输出如下:

rank = [1,4,3,2]

这意味着,对于任何并列名次,每个其他并列名次都会打破并列名次 并且所有其他后续位置也递增 1。这是一个简单的映射分配。

其他情况:

rank = [1,1,2,3] -> [1,2,3,4]
rank = [2,1,2,3] -> [2,1,3,4]
rank = [2,1,2,3] -> [2,1,3,4]
rank = [1,1,1,1] -> [1,2,3,4]

试试这个:

<?php

class Ranker 

{
private $rank, $result, $doWork;

public function rank() {

    $rank = array(
        "slot1" => 1,
        "slot2" => 1,
        "slot3" => 1,
        "slot4" => 1
        );
    $result = array();

    asort($rank);

    /* Get funky */
    foreach ($rank as $place) {

        $initialplace = $place;

        if (!empty($result)) {
             {
                while(in_array($place, $result)) {
                    $place++;
                    if (!in_array($place, $result)) {
                        break;
                    } 
                }
            }

            foreach (array_keys($rank, $initialplace) as $key) {

                if (!array_key_exists($key, $result)) {
                    $result[$key] = $place;
                    break;
                }

            }
        } else {
            /* array_search always returns first match */
            $result[array_search($initialplace, $rank)] = $initialplace;
        }
    }

    ksort($result);

    /* Printing it out */
    foreach ($result as $finalplace) {
        echo $finalplace . ' ' . array_search($finalplace, $result) . '</br>';
    }
}
}

/* Execute class function */
$ranker = new Ranker;
$doWork = $ranker->rank();

?>

好吧,这基本上是可行的,与上面的映射唯一不同的是,它会为平分分配平分,但我认为这并不重要。例如:

    $rank = array(
        "slot1" => 1,
        "slot2" => 1,
        "slot3" => 1,
        "slot4" => 1
        );

将return:

4 slot1
3 slot2
2 slot3
1 slot4

而不是 [1, 2, 3, 4]。因为他们都是并列的并且具有相同的 'initial rank/place/whatever' 我不认为这特别糟糕 - 也就是说你决定如何分配第二个获得'1'或第四个的人是任意的很快。

无论如何这是一个业务逻辑决策,并且由于您没有分享用例是什么,所以我真的不能说更多。但是,您似乎在实际 "break" 联系方式上有一定的灵活性。因此,如果您的用例和业务逻辑是灵活的,这就有效。否则,您可以稍微修改它以更符合上面列出的精确映射。