在数组数组中通过内消法进行二次排序
Secondary ranking by elimination within in an array of arrays
我正在根据下面的 json 示例数据编写一个高尔夫排名排行榜。我可以很容易地从低分(最好)到最高(差)来排列顺序,但是当涉及到“平局”时,这就是我想要弄清楚的问题。
这是一个简单的背景:array[0] 是最终得分,array[1] 是球队编号(T1、T2 等),array[2]-[10] 是每场连续投篮洞。将连续镜头相加并减去 36,这将等于每个团队的 array[0]。
现在应该根据每个洞的最低杆数依次“重新排名”决胜局。例如,当比较 T11、T2 和 T5 时……T2 应该排在总成绩第二位,因为他们在连续的第一个洞打了 3 杆,而 T11 和 T5 打了 4 杆。现在 T2 被“重新排名”为总成绩第二并且不在比较,T11 现在将与 T5 进行比较以进行下一次“重新排名”等等。如果有人能给我一个场景,我不是在寻找脚本,只是基本上需要临时提取按并列分数分割的并列球队,即提取 T11、T2 和 T5(-5 分数)进行比较并提取 T10 和 T9( -4 分数)以及 T!、T3、T4 和 T7(-3 分数)进行重新排名,然后将这些“重新排名”的段放回原始数组中,而不会扰乱未进行比较的团队他们的原始排名,即 T8(-7 分)和 T6(-1 分)。
{
[-7,"T8","4","3","3","4","4","2","3","3","3"],
[-5,"T11","4","3","4","4","4","3","3","3","3"],
[-5,"T2","3","3","4","4","4","3","3","4","3"],
[-5,"T5","4","4","3","4","4","3","4","3","2"],
[-4,"T10","4","3","4","4","4","2","4","4","3"],
[-4,"T9","4","3","3","4","5","3","3","3","4"],
[-3,"T1","5","3","3","4","4","3","4","4","3"],
[-3,"T3","4","3","4","4","4","3","4","4","3"],
[-3,"T4","4","3","3","4","5","3","4","3","4"],
[-3,"T7","4","4","4","4","3","3","4","4","3"],
[-1,"T6","4","3","3","4","5","4","4","4","4"]
}
谢谢。
一个简单的方法是将数组的连续镜头部分的比较添加到排序比较函数中。
usort($data, function($a, $b) {
return ($a[0] <=> $b[0]) ?: (array_slice($a, 2) <=> array_slice($b, 2));
});
第一部分 $a[0] <=> $b[0]
只是比较第一个元素,我认为这与您已经在做的类似。
第二部分 array_slice($a, 2) <=> array_slice($b, 2)
只有在第一部分由于 ?:
运算符而相等时才会被计算。
可以直接比较数组切片,因为PHP中比较数组的方式恰好就像你想要比较连续镜头的方式,如果我没理解错的话。只要数组大小相同,它们将一次只比较一个元素,从左到右(这在 PHP comparison operator documentation 中的“与各种类型的比较”table 中有描述)。
如果可以的话,我觉得如果能用队号索引数据会更方便,比如
[
"T8" => [-7,"4","3","3","4","4","2","3","3","3"],
"T11" => [-5,"4","3","4","4","4","3","3","3","3"],
...
]
那么你需要的排名就是
asort($data);
我正在根据下面的 json 示例数据编写一个高尔夫排名排行榜。我可以很容易地从低分(最好)到最高(差)来排列顺序,但是当涉及到“平局”时,这就是我想要弄清楚的问题。
这是一个简单的背景:array[0] 是最终得分,array[1] 是球队编号(T1、T2 等),array[2]-[10] 是每场连续投篮洞。将连续镜头相加并减去 36,这将等于每个团队的 array[0]。
现在应该根据每个洞的最低杆数依次“重新排名”决胜局。例如,当比较 T11、T2 和 T5 时……T2 应该排在总成绩第二位,因为他们在连续的第一个洞打了 3 杆,而 T11 和 T5 打了 4 杆。现在 T2 被“重新排名”为总成绩第二并且不在比较,T11 现在将与 T5 进行比较以进行下一次“重新排名”等等。如果有人能给我一个场景,我不是在寻找脚本,只是基本上需要临时提取按并列分数分割的并列球队,即提取 T11、T2 和 T5(-5 分数)进行比较并提取 T10 和 T9( -4 分数)以及 T!、T3、T4 和 T7(-3 分数)进行重新排名,然后将这些“重新排名”的段放回原始数组中,而不会扰乱未进行比较的团队他们的原始排名,即 T8(-7 分)和 T6(-1 分)。
{
[-7,"T8","4","3","3","4","4","2","3","3","3"],
[-5,"T11","4","3","4","4","4","3","3","3","3"],
[-5,"T2","3","3","4","4","4","3","3","4","3"],
[-5,"T5","4","4","3","4","4","3","4","3","2"],
[-4,"T10","4","3","4","4","4","2","4","4","3"],
[-4,"T9","4","3","3","4","5","3","3","3","4"],
[-3,"T1","5","3","3","4","4","3","4","4","3"],
[-3,"T3","4","3","4","4","4","3","4","4","3"],
[-3,"T4","4","3","3","4","5","3","4","3","4"],
[-3,"T7","4","4","4","4","3","3","4","4","3"],
[-1,"T6","4","3","3","4","5","4","4","4","4"]
}
谢谢。
一个简单的方法是将数组的连续镜头部分的比较添加到排序比较函数中。
usort($data, function($a, $b) {
return ($a[0] <=> $b[0]) ?: (array_slice($a, 2) <=> array_slice($b, 2));
});
第一部分 $a[0] <=> $b[0]
只是比较第一个元素,我认为这与您已经在做的类似。
第二部分 array_slice($a, 2) <=> array_slice($b, 2)
只有在第一部分由于 ?:
运算符而相等时才会被计算。
可以直接比较数组切片,因为PHP中比较数组的方式恰好就像你想要比较连续镜头的方式,如果我没理解错的话。只要数组大小相同,它们将一次只比较一个元素,从左到右(这在 PHP comparison operator documentation 中的“与各种类型的比较”table 中有描述)。
如果可以的话,我觉得如果能用队号索引数据会更方便,比如
[
"T8" => [-7,"4","3","3","4","4","2","3","3","3"],
"T11" => [-5,"4","3","4","4","4","3","3","3","3"],
...
]
那么你需要的排名就是
asort($data);