Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php,usort()在我想按顺序排序时失败_Php_Sorting - Fatal编程技术网

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不存在。根据您希望这些项目在列表中的显示方式,您可能需要将其设置为其他值(例如,如果希望它们显示在末尾,则设置为一个大数字)。