首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP usort()不准确?

PHP usort()不准确?
EN

Stack Overflow用户
提问于 2018-02-21 01:49:01
回答 2查看 37关注 0票数 0

我有一个多维数组。在每个数组中,它们是一个名为"elo-rating“的子值。我想根据这个子值对数组进行排序。

因此,我使用我的数组,名为$newRanks,并运行它如下:

代码语言:javascript
复制
uasort($newRanks, create_function(
    '$b, $a', 'return $a["elo_rating"] - $b["elo_rating"];'
));

在运行完该代码之后,我的数组返回如下:

代码语言:javascript
复制
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.639591461038.88789903下面。

有什么办法解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-21 02:00:07

您正在从函数中返回十进制值,文档对此发出警告。

如果第一个参数被认为分别小于、等于或大于第二个参数,则比较函数必须返回小于、等于或大于零的整数。注意,在PHP7.0.0之前,这个整数必须在-2147483648到2147483647之间。 请注意,从比较函数(如浮点数)返回非整数值将导致回调返回值的内部转换为整数。因此,0.99和0.1这样的值都将被转换为0的整数值,这将比较这些值是否相等。

更改您的函数以返回一个整数以修复此问题。

代码语言:javascript
复制
uasort($newRanks, create_function(
    '$b, $a', 'return ($a["elo_rating"] > $b["elo_rating"])?-1:1;'
));
票数 3
EN

Stack Overflow用户

发布于 2018-02-21 02:01:00

两个问题:

  1. 您使用的是create_function(),它在内部使用eval(),这是一个巨大的安全漏洞,不需要启动。只需使用一个实际的匿名函数。
  2. 函数参数是向后的。
  3. Willem Renzema对返回值的隐式转换提出了一个有效的观点,但我不喜欢这个解决方案。

所以:

代码语言:javascript
复制
$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是专门为此比较选择的值,其中您认为任何小于该值的$diff都是等价的,也就是浮点数/舍入错误。

请参阅:浮动和双比较最有效的方法是什么?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48897012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档