按地点对赛车手/玩家进行排序



我有一些关于赛车的数据,以以下形式呈现:

<>之前阵列(阵列(name =>"第一车手",地方=>(1、3、1、5、6,2,6,7,8)),数组(name => "第二名",名次=> [2,4,2,5,7])…)之前

建议最好的排序方式,以便第一个车手是谁有更好的地方。例如,如果第一个选手至少有一个第一名,而另一个选手没有,那么第一个选手在列表中的位置更高。如果它们都有第一名,比较第一名的数量。如果数字也相等,比较第二个位置,以此类推。

我的解决方案(它看起来不是很优雅。也许可以更简单地完成):

<>之前$racers = array(数组("名字"=>"第一车手","地方"=>(1、3、1、5、6、2、6、7,8,9)),数组("名字"=>"第二车手","地方"=>(1、3、1、5、6、2、6、7、8)),数组("名字"=>"第三车手","地方"=>[2、3、2、5、7、10]),数组("名字"=>"第四赛车","地方"=>[2、3、10 6 6 10]),数组("名字"=>"第五"、"地方"=>[2、3、2、5、7、10、1]),);ussort ($racers, function($prev, $next) {//为每个车手预订位置排序($上一页['的地方']);排序($下(的地方));//比较每个地方foreach ($prev['places'] AS $key => $prevRacerPlace) {//如果所有的值都相等,比较比赛的数量isset($next['places'][$key])) {返回1;}$nextRacerPlace = $next['places'][$key];$diff = $prevRacerPlace - $nextRacerPlace;If ($diff !== 0) {返回diff美元;}}//如果所有的值都相等,比较比赛的数量如果(count($下(的地方))>计数(美元上一页['的地方'])){返回1;}});var_dump(选手);

在自定义排序之前做一些准备是非常好的。因此,我们避免在lambda函数中嵌套排序:

foreach ($racers as $index => $racer) {
    $racers[$index]['sorted_places'] = $racer['places'];
    sort($racers[$index]['sorted_places']);
}

在排序lambda函数中,比较已排序位置的头并返回第一个定义值。如果racer B第一名的结果好于A,返回1。如果参赛者A排名第一的结果好于B,返回-1。对于相同的结果,继续检查下一个排名。

usort($racers, function ($a, $b) {
    unset($value);
    do {
        $topA = array_shift($a['sorted_places']);
        $topB = array_shift($b['sorted_places']);
        if (is_null($topA) && is_null($topB)) {
            $value = 0;
        } elseif (is_null($topA)) {
            $value = 1;
        } elseif (is_null($topB)) {
            $value = -1;
        } elseif ($topA > $topB) {
            $value = 1;
        } elseif ($topA < $topB) {
            $value = -1;
        }
    } while (!isset($value));
    return $value;
});

这里还有一个算法,但我认为Max Zuber的解决方案更有效。总之:

通过array_count_values

定义每个赛车的参赛名额
foreach ($racers as &$racer) {
    $racer['number_places'] = array_count_values($racer['places']);
}

和排序

usort($racers, function($current, $next) {
    $next_places = $next['number_places'];
    $current_places = $current['number_places'];
    for ($i=1; $i<=max($next_places, $current_places); $i++) {
        if (!isset($current_places[$i]) && !isset($next_places[$i])) {
            continue;
        }
        if (!isset($current_places[$i])) {
            return 1;
        }
        if (!isset($current_places[$i]) 
            || $current_places[$i] > $next_places[$i])
        {
            return -1;
        }
    }
});

最新更新