我有一个多维数组。在每个数组中,它们是一个名为" elo-rating"的子值。我想根据这个子值对数组进行排序。
所以我接受了名为$newRanks
的数组并通过以下方式运行它:
uasort($newRanks, create_function(
'$b, $a', 'return $a["elo_rating"] - $b["elo_rating"];'
));
运行该代码后,我的数组返回如下:
array:52 [
"3-1154" => array:4 [
"league_id" => 3
"user_id" => 1154
"elo_matches" => 8
"elo_rating" => 1224.47797881
]
"3-205" => array:4 [
"league_id" => 3
"user_id" => 205
"elo_matches" => 11
"elo_rating" => 1207.86593741
]
"3-1" => array:4 [
"league_id" => 3
"user_id" => 1
"elo_matches" => 17
"elo_rating" => 1206.60264689
]
"3-285" => array:4 [
"league_id" => 3
"user_id" => 285
"elo_matches" => 4
"elo_rating" => 1187.31524255
]
"3-259" => array:4 [
"league_id" => 3
"user_id" => 259
"elo_matches" => 4
"elo_rating" => 1173.02391767
]
"3-12689" => array:4 [
"league_id" => 3
"user_id" => 12689
"elo_matches" => 4
"elo_rating" => 1167.46830619
]
"3-1603" => array:4 [
"league_id" => 3
"user_id" => 1603
"elo_matches" => 13
"elo_rating" => 1153.3060092
]
"3-16" => array:4 [
"league_id" => 3
"user_id" => 16
"elo_matches" => 7
"elo_rating" => 1146.65083202
]
"3-1609" => array:4 [
"league_id" => 3
"user_id" => 1609
"elo_matches" => 3
"elo_rating" => 1122.679103
]
"3-333" => array:4 [
"league_id" => 3
"user_id" => 333
"elo_matches" => 5
"elo_rating" => 1112.56694511
]
"3-10030" => array:4 [
"league_id" => 3
"user_id" => 10030
"elo_matches" => 4
"elo_rating" => 1091.27782914
]
"3-378" => array:4 [
"league_id" => 3
"user_id" => 378
"elo_matches" => 9
"elo_rating" => 1082.0354022
]
"3-6107" => array:4 [
"league_id" => 3
"user_id" => 6107
"elo_matches" => 5
"elo_rating" => 1059.74850166
]
"3-5179" => array:4 [
"league_id" => 3
"user_id" => 5179
"elo_matches" => 3
"elo_rating" => 1046.60181418
]
"3-1476" => array:4 [
"league_id" => 3
"user_id" => 1476
"elo_matches" => 9
"elo_rating" => 1038.88789903
]
"3-70" => array:4 [
"league_id" => 3
"user_id" => 70
"elo_matches" => 8
"elo_rating" => 1038.63959146
]
"3-303" => array:4 [
"league_id" => 3
"user_id" => 303
"elo_matches" => 7
"elo_rating" => 1039.26666217
]
"3-59" => array:4 [
"league_id" => 3
"user_id" => 59
"elo_matches" => 1
"elo_rating" => 1033.78309445
]
"3-1017" => array:4 [
"league_id" => 3
"user_id" => 1017
"elo_matches" => 4
"elo_rating" => 1002.79264647
]
"3-632" => array:4 [
"league_id" => 3
"user_id" => 632
"elo_matches" => 3
"elo_rating" => 1002.2039368
]
"3-177" => array:4 [
"league_id" => 3
"user_id" => 177
"elo_matches" => 4
"elo_rating" => 994.838857477
]
"3-12466" => array:4 [
"league_id" => 3
"user_id" => 12466
"elo_matches" => 4
"elo_rating" => 994.761652125
]
"3-9725" => array:4 [
"league_id" => 3
"user_id" => 9725
"elo_matches" => 7
"elo_rating" => 994.520367143
]
"3-1593" => array:4 [
"league_id" => 3
"user_id" => 1593
"elo_matches" => 4
"elo_rating" => 987.448354356
]
"3-78" => array:4 [
"league_id" => 3
"user_id" => 78
"elo_matches" => 16
"elo_rating" => 984.927509938
]
"3-20837" => array:4 [
"league_id" => 3
"user_id" => 20837
"elo_matches" => 4
"elo_rating" => 981.533602402
]
"3-25" => array:4 [
"league_id" => 3
"user_id" => 25
"elo_matches" => 3
"elo_rating" => 977.651701927
]
"3-2056" => array:4 [
"league_id" => 3
"user_id" => 2056
"elo_matches" => 8
"elo_rating" => 978.374247502
]
"3-14300" => array:4 [
"league_id" => 3
"user_id" => 14300
"elo_matches" => 9
"elo_rating" => 958.218292232
]
"3-16900" => array:4 [
"league_id" => 3
"user_id" => 16900
"elo_matches" => 3
"elo_rating" => 957.66758785
]
"3-5" => array:4 [
"league_id" => 3
"user_id" => 5
"elo_matches" => 3
"elo_rating" => 955.441682773
]
"3-11793" => array:4 [
"league_id" => 3
"user_id" => 11793
"elo_matches" => 3
"elo_rating" => 956.118019821
]
"3-23" => array:4 [
"league_id" => 3
"user_id" => 23
"elo_matches" => 1
"elo_rating" => 950.0
]
"3-160" => array:4 [
"league_id" => 3
"user_id" => 160
"elo_matches" => 6
"elo_rating" => 946.346810828
]
"3-11882" => array:4 [
"league_id" => 3
"user_id" => 11882
"elo_matches" => 3
"elo_rating" => 943.113557791
]
"3-178" => array:4 [
"league_id" => 3
"user_id" => 178
"elo_matches" => 3
"elo_rating" => 940.38037017
]
"3-2113" => array:4 [
"league_id" => 3
"user_id" => 2113
"elo_matches" => 3
"elo_rating" => 940.343382565
]
"3-1334" => array:4 [
"league_id" => 3
"user_id" => 1334
"elo_matches" => 2
"elo_rating" => 923.336202927
]
"3-184" => array:4 [
"league_id" => 3
"user_id" => 184
"elo_matches" => 2
"elo_rating" => 920.326252901
]
"3-2162" => array:4 [
"league_id" => 3
"user_id" => 2162
"elo_matches" => 2
"elo_rating" => 917.932985501
]
"3-2058" => array:4 [
"league_id" => 3
"user_id" => 2058
"elo_matches" => 6
"elo_rating" => 905.641833006
]
"3-1951" => array:4 [
"league_id" => 3
"user_id" => 1951
"elo_matches" => 2
"elo_rating" => 906.136056131
]
"3-1749" => array:4 [
"league_id" => 3
"user_id" => 1749
"elo_matches" => 2
"elo_rating" => 905.570092295
]
"3-15296" => array:4 [
"league_id" => 3
"user_id" => 15296
"elo_matches" => 2
"elo_rating" => 901.02829192
]
"3-11684" => array:4 [
"league_id" => 3
"user_id" => 11684
"elo_matches" => 2
"elo_rating" => 901.02829192
]
"3-940" => array:4 [
"league_id" => 3
"user_id" => 940
"elo_matches" => 2
"elo_rating" => 899.735074733
]
"3-12235" => array:4 [
"league_id" => 3
"user_id" => 12235
"elo_matches" => 2
"elo_rating" => 900.0
]
"3-2957" => array:4 [
"league_id" => 3
"user_id" => 2957
"elo_matches" => 2
"elo_rating" => 900.0
]
"3-14959" => array:4 [
"league_id" => 3
"user_id" => 14959
"elo_matches" => 2
"elo_rating" => 894.798068073
]
"3-779" => array:4 [
"league_id" => 3
"user_id" => 779
"elo_matches" => 5
"elo_rating" => 874.675970857
]
"3-110" => array:4 [
"league_id" => 3
"user_id" => 110
"elo_matches" => 4
"elo_rating" => 849.309123925
]
"3-5837" => array:4 [
"league_id" => 3
"user_id" => 5837
"elo_matches" => 4
"elo_rating" => 821.601462523
]
]
如果你仔细观察这个结果数组,你会注意到它没有完全正确排序。例如,它将1039.26666217
置于1038.63959146
和1038.88789903
之下。
有关如何解决此问题的任何想法?
答案 0 :(得分:3)
您将从函数返回十进制值,documentation警告。
比较函数必须返回小于,等于或的整数 如果第一个参数被认为是大于零 分别小于,等于或大于第二个。注意 在PHP 7.0.0之前,这个整数必须在以下范围内 -2147483648至2147483647。
警告从比较函数返回非整数值, 比如float,会导致内部强制转换为整数 回调的回报值。因此,诸如0.99和0.1之类的值都将是 强制转换为0的整数值,这将比较这些值 相等。
更改您的函数以返回一个整数来解决问题。
uasort($newRanks, create_function(
'$b, $a', 'return ($a["elo_rating"] > $b["elo_rating"])?-1:1;'
));
答案 1 :(得分:1)
两个问题:
create_function()
的{{1}},这是一个巨大的安全漏洞,无需启动。只需使用实际的匿名函数。所以:
eval()
其中$epsilon = 0.000000001;
uasort(
$newRanks,
function($a,$b)use($epsilon}{
$diff = $a["elo_rating"] - $b["elo_rating"];
if( abs($diff) < $epsilon ) { return 0; }
else if( $diff > 0 ) { return 1; }
else { return -1; }
)
);
是专门为此比较选择的值,您认为任何$epsilon
小于等值,即浮点/舍入误差。
请参阅:What is the most effective way for float and double comparison?