PHP多维数组按用户名升序、子数组日期降序排序实现方案
PHP多维用户状态数组双层排序实现
场景说明
现有存储用户状态变更记录的多维数组$allStatusChanges,结构规则如下:
- 数组一级键名为用户姓名,对应值为该用户的多条状态变更记录子数组集合
- 每条状态记录子数组包含
name、date、Departament、Domain、status change字段 - 排序要求:
- 所有用户按用户名做整体升序排列
- 单个用户名下的多条状态变更记录,按
date字段做降序排列
原有代码问题
原有实现代码如下,无法满足排序需求:
$date = []; $name = []; foreach ($allStatusChanges as $users=>$values){ foreach ($values as $value){ $name[$users] = $value['name']; $date[$users][]=date('Y-m-d', strtotime($value['date'])); array_multisort( $name, SORT_ASC, $allStatusChanges); } }
核心问题:
- 把全量排序函数
array_multisort写在内层循环中,每次单条记录遍历都会触发全数组重排,逻辑冗余结果不可控 - 没有针对每个用户名下的记录子集单独做日期维度的排序处理
正确实现代码
// 外层:按一级键(用户名)字符串升序排序 ksort($allStatusChanges, SORT_STRING); // 内层:遍历每个用户的记录集合,按日期降序排序 foreach ($allStatusChanges as $user => &$changeLogs) { usort($changeLogs, function($prev, $next) { $prevTime = strtotime($prev['date']); $nextTime = strtotime($next['date']); // PHP7.0+ 用太空船运算符直接比较,低版本替换为 return $nextTime - $prevTime; return $nextTime <=> $prevTime; }); } // 解除遍历引用,避免后续逻辑误修改原数组 unset($changeLogs);
注意事项
- 若使用PHP版本低于7.0,不支持太空船运算符
<=>,将比较函数返回值替换为return $nextTime - $prevTime;即可实现相同降序效果 - 日期排序基于
strtotime转换的时间戳实现,要求date字段值为strtotime可识别的标准日期格式 - 引用遍历结束后必须
unset引用变量,否则后续对同名变量的赋值会直接修改原数组最后一项的内容
内容的提问来源于stack exchange,提问作者Olga
相关产品推荐
相关产品推荐

