【问题标题】:Sorting 3 dimensional array at 2nd level based on 3rd level values根据第 3 级值对第 2 级的 3 维数组进行排序
【发布时间】:2016-01-30 03:36:11
【问题描述】:

我正在使用 Google Calendar API 从多个日历中提取数据。我正在创建一个数组,以便我可以格式化数据的显示。我无法对数据进行排序,因此事件将按正确的顺序显示。

我的主要排序是datetime ASC。如果两个日期时间相等,我想按alldayflag DESC 排序。我只希望它在每个日期内排序。

这是我的数据示例:

Array 
( 
[2016-01-29] => Array 
    ( 
        [0] => Array 
            ( 
                [date] => January 29 
                [time] => 8:30 am 
                [datetime] => 2016-01-29T08:30:00-06:00 
                [alldayflag] => 0 
            ) 
        [1] => Array 
            ( 
                [date] => January 29 
                [time] => 12:00 am 
                [datetime] => 2016-01-29T00:00:00-06:00 
                [alldayflag] => 1 
            ) 
        [2] => Array 
            ( 
                [date] => January 29 
                [time] => 2:00 pm 
                [datetime] => 2016-01-29T14:00:00-06:00 
                [alldayflag] => 0 
            ) 
        [3] => Array 
            ( 
                [date] => January 29 
                [time] => 10:00 am 
                [datetime] => 2016-01-29T10:00:00-06:00 
                [alldayflag] => 0 
            ) 
        [4] => Array 
            ( 
                [date] => January 29 
                [time] => 12:00 pm 
                [datetime] => 2016-01-29T12:00:00-06:00 
                [alldayflag] => 0 
            ) 
    ) 
[2016-01-30] => Array 
    ( 
        [0] => Array 
            ( 
                [date] => January 30 
                [time] => 4:00 pm 
                [datetime] => 2016-01-30T16:00:00-06:00 
                [alldayflag] => 0 
            ) 
        [1] => Array 
            ( 
                [date] => January 30 
                [time] => 5:00 pm 
                [datetime] => 2016-01-30T17:00:00-06:00 
                [alldayflag] => 0 
            ) 
        [2] => Array 
            ( 
                [date] => January 30 
                [time] => 11:00 am 
                [datetime] => 2016-01-30T11:00:00-06:00 
                [alldayflag] => 0 
            ) 
    ) 
)

我尝试过使用array_multisort()。我得到了正确的排序结果,但我也得到了错误消息:

警告:array_multisort(): 数组大小在第 XXX 行的 sort-array.php 中不一致

$getBeginDate = '2016-01-29';
$getEndDate = '2016-01-31';

$getCurrentDate = $getBeginDate;

while(strtotime($getCurrentDate) < strtotime($getEndDate)) {

    foreach ($list[$getCurrentDate] as $key => $row){
         $datetime[$key] = $row['datetime'];
         $alldayflag[$key] = $row['alldayflag'];
    }

    array_multisort($datetime, SORT_ASC, $alldayflag, SORT_DESC, $list[$getCurrentDate]);

    $getCurrentDate = date('Y-m-d', strtotime($getCurrentDate . " +1 day"));

}

我也试过uasort()。它根本无法正确排序。

uasort($list, 'sortCriteria');

function sortCriteria($array, $key) {
    if(strtotime($a['datetime']) == strtotime($b['datetime'])) {
        if($a['allday'] < $b['allday']) {
            return -1;
        } else {
            return 0;
        }
    }

    return (strtotime($a['datetime']) < strtotime($b['datetime'])) ? -1 : 1;

}

非常感谢任何帮助。

【问题讨论】:

    标签: php arrays sorting multidimensional-array array-multisort


    【解决方案1】:

    array_multisort 绝对是您想要的方式。我有一个未经测试的答案给你,所以如果这是一个不正确的猜测,我可能会被社区的愤怒所打击,但看起来你遇到了关闭问题,或者更确切地说是缺乏关闭问题。这应该可以解决您的问题:

    ...
    while(strtotime($getCurrentDate) < strtotime($getEndDate)) {
    
    $datetime = [];
    $alldayflag = [];
    foreach ($list[$getCurrentDate] as $key => $row){
    ...
    

    我从您提到的错误中猜测是,如果您在多排序之前转储 $datetime,第一次将有 5 个项目,第二次将有 5 个项目。

    first_dump => '29th', '29th', '29th', '29th', '29th'
    second_dump => '30th', '30th', '30th', '29th', '29th'
    

    或类似的东西。发生的事情是 $datetime 在第一轮 while 循环中持续到第二次。这是第二次炸毁您的多排序,因为只有 3 个项目而不是 5 个。

    我希望这是有道理的。

    【讨论】:

    • 是的,这完全有道理。我进行了更改,它解决了我的问题。极好的!这是一个如此简单的解决方案。谢谢你快速的回复。这是我只需要一个新鲜的人来查看代码的时候之一。
    【解决方案2】:

    一个可能的解决方案是使用usort。 然后您可以使用DateTime 来比较“日期时间”。 然后如果两个日期时间相等,您可以比较“alldayflag”。

    例如:

    function sortCriteria($a, $b)
    {
        $aDateTime = new DateTime($a['datetime']);
        $bDateTime = new DateTime($b['datetime']);
    
        if ($aDateTime == $bDateTime) {
            return ($a['alldayflag'] > $b['alldayflag']) ? -1 : 1;
        }
    
        return ($aDateTime < $bDateTime) ? -1 : 1;
    }
    
    $getBeginDate = '2016-01-29';
    $getEndDate = '2016-01-31';
    $getCurrentDate = $getBeginDate;
    
    while(strtotime($getCurrentDate) < strtotime($getEndDate)) {
        usort($list[$getCurrentDate], 'sortCriteria');
        $getCurrentDate = date('Y-m-d', strtotime($getCurrentDate . " +1 day"));
    }
    

    Demo

    【讨论】:

    • 我看到它在示例数据上正常工作,但由于某种原因它不能在我的实时数据上工作。我会多看看这个,看看我是否能弄清楚出了什么问题。我确实找到了我的 array_multisort 的解决方案,但我有兴趣了解这是否也可以是一个解决方案。
    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2018-08-17
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多