根据第 3 级值在第 2 级对 3 维数组进行排序
Sorting 3 dimensional array at 2nd level based on 3rd level values
我正在使用 Google 日历 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()
。我得到了正确的排序结果,但是我也收到了错误消息:
Warning: array_multisort(): Array sizes are inconsistent in sort-array.php on line XXX
$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;
}
非常感谢任何帮助。
array_multisort
绝对是你想走的路。我有一个未经测试的答案给你,所以如果这是一个错误的猜测,我可能会被社区的愤怒击中,但看起来你 运行 陷入了关闭问题,或者更确切地说是缺乏关闭问题。这应该可以解决您的问题:
...
while(strtotime($getCurrentDate) < strtotime($getEndDate)) {
$datetime = [];
$alldayflag = [];
foreach ($list[$getCurrentDate] as $key => $row){
...
根据您提到的错误,我的猜测是,如果您在 multisort 之前转储 $datetime
,它将在第一次中包含 5 个项目,在第二次中包含 5 个项目。
first_dump => '29th', '29th', '29th', '29th', '29th'
second_dump => '30th', '30th', '30th', '29th', '29th'
或类似的东西。发生的事情是 $datetime 在 while 循环的第一轮持续到第二轮。这是第二次轰炸你的多重排序,因为只有 3 个项目而不是 5 个。
我希望这是有道理的。
一个可能的解决方案是使用 usort。
然后,您可以使用 DateTime 来比较 '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"));
}
我正在使用 Google 日历 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()
。我得到了正确的排序结果,但是我也收到了错误消息:
Warning: array_multisort(): Array sizes are inconsistent in sort-array.php on line XXX
$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;
}
非常感谢任何帮助。
array_multisort
绝对是你想走的路。我有一个未经测试的答案给你,所以如果这是一个错误的猜测,我可能会被社区的愤怒击中,但看起来你 运行 陷入了关闭问题,或者更确切地说是缺乏关闭问题。这应该可以解决您的问题:
...
while(strtotime($getCurrentDate) < strtotime($getEndDate)) {
$datetime = [];
$alldayflag = [];
foreach ($list[$getCurrentDate] as $key => $row){
...
根据您提到的错误,我的猜测是,如果您在 multisort 之前转储 $datetime
,它将在第一次中包含 5 个项目,在第二次中包含 5 个项目。
first_dump => '29th', '29th', '29th', '29th', '29th'
second_dump => '30th', '30th', '30th', '29th', '29th'
或类似的东西。发生的事情是 $datetime 在 while 循环的第一轮持续到第二轮。这是第二次轰炸你的多重排序,因为只有 3 个项目而不是 5 个。
我希望这是有道理的。
一个可能的解决方案是使用 usort。 然后,您可以使用 DateTime 来比较 '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"));
}