我有一些关于赛车的数据,以以下形式呈现:
<>之前阵列(阵列(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;
}
}
});