PHP如何通过usort结合多组自定义顺序数组排序WordPress ACF字段结果
解决方案
两个自定义排序规则可以合并到同一个usort回调中实现层级排序:先按第一优先级(尺寸)排序,只有两个元素的尺寸排序位置相同时,再按第二优先级(颜色)排序。
基础实现代码
$sizeOrder = ['Small', 'Medium', 'Large']; $colorOrder = ['White', 'Blue', 'Black']; usort($data, function ($a, $b) use ($sizeOrder, $colorOrder) { // 先比较尺寸排序优先级 $posA_size = array_search($a['acf']['product_size'], $sizeOrder); $posB_size = array_search($b['acf']['product_size'], $sizeOrder); $sizeDiff = $posA_size - $posB_size; // 尺寸位置不同,直接返回尺寸排序结果 if ($sizeDiff !== 0) { return $sizeDiff; } // 尺寸相同的场景下,再比较颜色排序 $posA_color = array_search($a['acf']['product_color'], $colorOrder); $posB_color = array_search($b['acf']['product_color'], $colorOrder); return $posA_color - $posB_color; });
原写法失效原因
两次独立调用usort时,第二次排序会完全重新排列整个数组,直接覆盖第一次的尺寸排序结果,只有在同一个回调内按优先级顺序判断,才能保留多字段排序的层级关系。
性能优化版实现
如果数据量较大,可以提前把排序规则数组翻转成键值映射,把array_search的O(n)查找复杂度降为O(1),同时兼容不存在的字段值默认排到末尾:
// 翻转数组,用键存字段值,值存排序优先级,查找更快 $sizeOrder = array_flip(['Small', 'Medium', 'Large']); $colorOrder = array_flip(['White', 'Blue', 'Black']); usort($data, function ($a, $b) use ($sizeOrder, $colorOrder) { // 不存在的字段值默认赋予最大优先级,排到列表末尾 $posA_size = $sizeOrder[$a['acf']['product_size']] ?? PHP_INT_MAX; $posB_size = $sizeOrder[$b['acf']['product_size']] ?? PHP_INT_MAX; $sizeDiff = $posA_size - $posB_size; if ($sizeDiff !== 0) { return $sizeDiff; } $posA_color = $colorOrder[$a['acf']['product_color']] ?? PHP_INT_MAX; $posB_color = $colorOrder[$b['acf']['product_color']] ?? PHP_INT_MAX; return $posA_color - $posB_color; });
如果需要调整排序优先级(比如先按颜色排序、同颜色再按尺寸排序),只要交换代码中尺寸和颜色的判断顺序即可。
内容的提问来源于stack exchange,提问作者user13286
相关产品推荐
相关产品推荐

