PHP:在循环内使用usort()对多维数组排序
多维数组(含对象)排序解决方案
嘿,我来帮你搞定这个多维数组的排序问题!先把你给出的数组结构整理得更清晰,方便我们分析:
$yourArray = [ 1 => (object)[ 'events' => [ (object)[ 'id' => 1, 'task' => 'task1', 'date_task' => '2018-04-02', 'start' => 8, 'end' => 10 ], (object)[ 'id' => 7, 'task' => 'task 32', 'date_task' => '2018-04-02', 'start' => 10, 'end' => 12 ] ] ], 2 => (object)[ 'events' => [ (object)[ 'id' => 4, 'task' => '...', // 你未补充完整的任务内容 // 对应任务的其他属性 ] ] ] ];
根据常见的排序需求,我给你两种最实用的解决方案:
方案一:每个子对象的events数组内部排序
如果你想让每个外层对象里的任务列表,按日期+开始时间从小到大排序,用usort配合匿名函数就能轻松实现:
// 遍历外层数组的每个对象 foreach ($yourArray as $item) { // 对当前对象的events数组进行排序 usort($item->events, function($a, $b) { // 先比较日期:YYYY-MM-DD格式的字符串可直接用strcmp比较大小 $dateDiff = strcmp($a->date_task, $b->date_task); if ($dateDiff !== 0) { return $dateDiff; } // 日期相同的话,再比较开始时间(数字直接相减即可判断先后) return $a->start - $b->start; }); }
处理后,每个events数组里的任务会按「日期早的在前,同日期下开始时间早的在前」的规则排列。
方案二:把所有任务提取出来整体排序
如果你想把所有外层对象里的任务合并成一个列表,再统一按日期和时间排序,甚至重新按日期分组,可以这么做:
// 第一步:提取所有events到一个统一数组 $allEvents = []; foreach ($yourArray as $item) { $allEvents = array_merge($allEvents, $item->events); } // 第二步:对合并后的所有任务排序 usort($allEvents, function($a, $b) { $dateDiff = strcmp($a->date_task, $b->date_task); if ($dateDiff !== 0) { return $dateDiff; } return $a->start - $b->start; }); // 可选操作:如果需要重新按日期归类任务 $sortedGrouped = []; foreach ($allEvents as $event) { $date = $event->date_task; if (!isset($sortedGrouped[$date])) { $sortedGrouped[$date] = []; } $sortedGrouped[$date][] = $event; }
自定义排序规则调整
如果你需要其他排序逻辑,只需要修改匿名函数的返回值即可:
- 倒序排序:把
return $dateDiff;改成return -$dateDiff;,return $a->start - $b->start;改成return $b->start - $a->start; - 按结束时间排序:把
$a->start替换成$a->end即可
内容的提问来源于stack exchange,提问作者Abdes
相关产品推荐
相关产品推荐

