PHP 按自定义AgingType顺序重排stdClass对象组成的Aging数组
问题排查与实现方案
为什么直接调用usort($summary->Aging)无法生效
之前的写法有两个硬伤:
usort必须传入自定义比较回调函数,才能实现符合要求的非默认排序。不带回调的默认排序仅针对数字、字符串这类标量设计,完全识别不了数组里stdClass对象的属性逻辑- 就算走默认排序逻辑,也根本不会匹配你指定的
AgingType自定义顺序,自然达不到“把Not Due移到数组最开头”的目标
具体实现方法
第一步:提前定义自定义顺序的权重映射
把目标排序顺序,对应成从小到大的权重值,权重越小,排序后位置越靠前:
$orderWeightMap = [ 'Not Due' => 0, '< 30' => 1, '31 to 60' => 2, '61-90' => 3, '91-180' => 4, '181-360' => 5, '361-720' => 6, '> 720' => 7, ];
第二步:带自定义回调执行排序
把排序逻辑写在回调函数里,逐个提取两个待比较对象的AgingType属性,通过映射表对比权重差完成排序,同时加兜底逻辑,避免遇到没定义的AgingType时报错:
usort($summary->Aging, function($itemA, $itemB) use ($orderWeightMap) { // 提取当前两个元素的对应权重,未在映射表里的未知类型给最大权重,排在数组最后 $weightA = $orderWeightMap[$itemA->AgingType] ?? 999; $weightB = $orderWeightMap[$itemB->AgingType] ?? 999; // 权重差决定排序顺序:返回值为负,就把itemA排在itemB前面 return $weightA - $weightB; });
多组同类数组的批量处理
如果存在多组结构完全一致的Aging数组,只需要在循环里套用上述排序逻辑就行:
foreach ($allAgingCollection as &$singleAgingGroup) { usort($singleAgingGroup, function($itemA, $itemB) use ($orderWeightMap) { $weightA = $orderWeightMap[$itemA->AgingType] ?? 999; $weightB = $orderWeightMap[$itemB->AgingType] ?? 999; return $weightA - $weightB; }); } // 循环结束后断开引用,避免后续操作误改最后一组数据 unset($singleAgingGroup);
关键注意点
- 映射表的键名必须和实际
AgingType的内容完全匹配,包括符号、空格(比如< 30前后的空格、61-90的连接符都不能写错),不然会触发兜底逻辑,把对应项排到数组末尾 usort是直接修改原数组的,排序完成后不需要重新给原变量赋值
内容的提问来源于stack exchange,提问作者user3386779
相关产品推荐
相关产品推荐

