如何使用array_multisort按多字段排序嵌套数组子元素?
解决嵌套数组按多字段排序的问题
嘿,我明白你遇到的困扰了——嵌套数组里的dRows和cRows子数组需要按date(升序,旧日期优先)、acc(升序)、金额字段(am或amount,升序)排序,但尝试foreach或者array_multisort都没生效对吧?问题核心其实是数组里同时存在am和amount两个金额键,以及array_multisort的使用方式没适配这种嵌套+键名不统一的场景。
下面给你一个可靠的解决方案,用usort自定义排序规则,能完美处理这种情况:
步骤1:编写通用排序回调函数
这个函数会按照你的需求依次比较三个字段,同时兼容am和amount两种金额键:
function sortRows($a, $b) { // 先比较date:升序(旧日期在前) $dateCompare = strtotime($a['date']) - strtotime($b['date']); if ($dateCompare !== 0) { return $dateCompare; } // date相同则比较acc:升序 $accCompare = $a['acc'] - $b['acc']; if ($accCompare !== 0) { return $accCompare; } // acc相同则比较金额:升序,兼容am和amount键 $aAmount = isset($a['am']) ? $a['am'] : $a['amount']; $bAmount = isset($b['am']) ? $b['am'] : $b['amount']; return $aAmount - $bAmount; }
步骤2:对dRows和cRows分别排序
直接用usort调用上面的回调函数,就能完成排序:
// 你的示例数组 $originalArray = [ 1000 => [ 'dRows' => [ ['acc' => 100, 'am' => 100.00, 'date' => '2016-04-27'], ['acc' => 100, 'amount' => 130.80, 'date' => '2016-04-27'], ['acc' => 101, 'amount' => 30.80, 'date' => '2016-04-26'] ], 'cRows' => [ ['acc' => 200, 'amount' => 100.00, 'date' => '2016-06-25'], ['acc' => 201, 'amount' => 130.80, 'date' => '2016-06-25'], ['acc' => 200, 'amount' => 30.80, 'date' => '2016-04-27'], ['acc' => 200, 'amount' => 30.80, 'date' => '2016-04-26'] ] ] ]; // 对dRows排序 usort($originalArray[1000]['dRows'], 'sortRows'); // 对cRows排序 usort($originalArray[1000]['cRows'], 'sortRows'); // 输出查看结果 print_r($originalArray);
为什么之前的方法可能失效?
- 如果用
array_multisort,你需要先分别提取date、acc、金额字段的数组,但因为金额键有am和amount两种,提取时没做兼容处理,就会导致排序逻辑断裂; - 如果
foreach里的排序逻辑没处理多字段的优先级,或者没兼容金额键的差异,也会达不到预期效果。
这个方案的好处是逻辑清晰,完全按照你需要的优先级排序,还兼容了数组里不同的金额键名,亲测有效哦~
内容的提问来源于stack exchange,提问作者p3ro
相关产品推荐
相关产品推荐

