Php,usort()在我想按顺序排序时失败
让我们有一个初始数组:Php,usort()在我想按顺序排序时失败,php,sorting,Php,Sorting,让我们有一个初始数组: $hits = [ ['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 1], ['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 4], ['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' =
$hits = [
['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 1],
['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 4],
['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 2],
['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 1],
['date' => new \DateTime('2019-01-01 12:00:00'), 'roundIndex' => 1],
['date' => new \DateTime('2019-01-04 12:00:00'), 'roundIndex' => 4],
['date' => new \DateTime('2019-01-02 12:00:00'), 'roundIndex' => 2],
['date' => new \DateTime('2019-01-23 12:00:00'), 'roundIndex' => 1],
['date' => new \DateTime('2019-01-22 12:00:00'), 'roundIndex' => 6],
['date' => new \DateTime('2019-01-01 12:00:00'), 'roundIndex' => 3],
['date' => new \DateTime('2019-01-06 12:00:00'), 'roundIndex' => 2],
['date' => new \DateTime('2019-01-28 12:00:00'), 'roundIndex' => 7],
['date' => new \DateTime('2019-01-26 12:00:00'), 'roundIndex' => 3],
['date' => new \DateTime('2019-01-27 12:00:00'), 'roundIndex' => 5],
['date' => new \DateTime('2019-01-26 12:00:00'), 'roundIndex' => 2],
['date' => new \DateTime('2019-01-11 12:00:00'), 'roundIndex' => 4],
['date' => new \DateTime('2019-01-24 12:00:00'), 'roundIndex' => 3],
['date' => new \DateTime('2019-01-08 12:00:00'), 'roundIndex' => 7],
['date' => new \DateTime('2019-01-11 12:00:00'), 'roundIndex' => 8],
['date' => new \DateTime('2019-01-14 12:00:00'), 'roundIndex' => 6],
['date' => new \DateTime('2019-01-13 12:00:00'), 'roundIndex' => 4],
['date' => new \DateTime('2019-01-13 12:00:00'), 'roundIndex' => 5],
['date' => new \DateTime('2019-01-24 12:00:00'), 'roundIndex' => 2],
['date' => new \DateTime('2019-01-27 12:00:00'), 'roundIndex' => 4],
];
我想按日期排序,如果日期相等,则按roundIndex排序。考虑到“roundIndex”可能不存在
第一:
usort($hits, static function(array $item1, array $item2) {
return $item1['date'] < $item2['date'] ? -1 : 1;
});
到目前为止还不错。所以第二个排序:
usort($hits, function($a,$b) use ($defaults) {
if (
$a['date']->format('Y-m-d H:i:s') === $b['date']->format('Y-m-d H:i:s'))
{
if ($a['roundIndex'] > $b['roundIndex'])
{
return 1;
}
else
{
return -1;
}
}
return 0;
});
结果现在有点搞砸了:
2019-01-08 12:00:00 7
2019-01-04 12:00:00 4
2019-01-06 12:00:00 2
2019-01-02 12:00:00 1
2019-01-02 12:00:00 1
2019-01-02 12:00:00 2
2019-01-02 12:00:00 2
2019-01-02 12:00:00 4
2019-01-11 12:00:00 4
2019-01-11 12:00:00 8
2019-01-27 12:00:00 4
2019-01-26 12:00:00 3
2019-01-24 12:00:00 2
2019-01-26 12:00:00 2
2019-01-23 12:00:00 1
2019-01-24 12:00:00 3
2019-01-22 12:00:00 6
2019-01-14 12:00:00 6
2019-01-13 12:00:00 4
2019-01-13 12:00:00 5
2019-01-01 12:00:00 3
2019-01-27 12:00:00 5
2019-01-28 12:00:00 7
2019-01-01 12:00:00 1
我真的不明白,为什么。但如果我手动订购:
$sizeOfHits = sizeof($hits);
for($i = 0; $i < $sizeOfHits; $i++)
{
for($j = $i+1; $j < $sizeOfHits; $j++)
{
if (
$hits[$i]['date']->format('Y-m-d H:i:s') === $hits[$j]['date']->format('Y-m-d H:i:s'))
{
if ($hits[$i]['roundIndex'] > $hits[$j]['roundIndex'])
{
$x = $hits[$j];
$hits[$j] = $hits[$i];
$hits[$i] = $x;
}
}
}
}
$sizeOfHits=sizeof($hits);
对于($i=0;$i<$sizeOfHits;$i++)
{
对于($j=$i+1;$j<$sizeOfHits;$j++)
{
如果(
$hits[$i]['date']->格式('Y-m-dh:i:s')====$hits[$j]['date']->格式('Y-m-dh:i:s'))
{
如果($hits[$i]['roundIndex']>$hits[$j]['roundIndex']))
{
$x=$hits[$j];
$hits[$j]=$hits[$i];
$hits[$i]=$x;
}
}
}
}
所有的结果都是完美的!但将有10000个元素,并且据测量,通过手动订购,需要20-30秒
您可以在这里尝试一下:我想这就足够了:
usort($hits, function($a, $b) {
// You can compare DateTime objects directly
if ($a['date'] == $b['date']) {
// use ?? to check if `roundIndex` exists
return ($a['roundIndex'] ?? 0) - ($b['roundIndex'] ?? 0);
}
return $a['date'] > $b['date'];
});
我想这已经足够了:
usort($hits, function($a, $b) {
// You can compare DateTime objects directly
if ($a['date'] == $b['date']) {
// use ?? to check if `roundIndex` exists
return ($a['roundIndex'] ?? 0) - ($b['roundIndex'] ?? 0);
}
return $a['date'] > $b['date'];
});
请原谅这个极其简洁的解决方案,但它基本上使用spaceship操作符(
)比较日期,如果比较日期的结果为假(即它们相等),则返回roundIndex值的比较
usort($hits, function($a,$b) {
return $a['date'] <=> $b['date'] ?:
($a['roundIndex']??0) <=> ($b['roundIndex']??0);
});
usort($hits,function($a,$b){
返回$a['date']$b['date']?:
($a['roundIndex']??0)($b['roundIndex']??0);
});
请原谅这个极其简洁的解决方案,但它基本上使用spaceship操作符(
)比较日期,如果比较日期的结果为假(即它们相等),则返回roundIndex值的比较
usort($hits, function($a,$b) {
return $a['date'] <=> $b['date'] ?:
($a['roundIndex']??0) <=> ($b['roundIndex']??0);
});
usort($hits,function($a,$b){
返回$a['date']$b['date']?:
($a['roundIndex']??0)($b['roundIndex']??0);
});
问题是,在测试中,你说如果日期是==
,但如果不是,你只返回0,这意味着它们是相同的值(如果有意义的话),但如果我返回1而不是0,如果日期不匹配,它仍然会出错,然后你需要返回+/-1来表示哪个更大。问题是在测试中,你说如果日期是==
,但如果不是,你只返回0,这意味着它们是相同的值(如果有意义),但如果我返回1而不是0,如果日期不匹配,它仍然会出错,然后你需要返回+/-1以指示哪个更大。这并不是那么简单,需要第二轮排序(不能混合到一个排序中)。而且“roundIndex”并不总是存在。不知道为什么你说它不能混合成一种类型?我已将代码更新为使用??0
以防roundIndex不存在。根据您希望这些项目在列表中的显示方式,您可能需要将其设置为其他值(例如,如果希望它们显示在末尾,则设置为一个大数字)。这并不是那么简单,需要进行第二轮排序(不能混合到一个排序中)。而且“roundIndex”并不总是存在。不知道为什么你说它不能混合成一种类型?我已将代码更新为使用??0
以防roundIndex不存在。根据您希望这些项目在列表中的显示方式,您可能需要将其设置为其他值(例如,如果希望它们显示在末尾,则设置为一个大数字)。