You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel按多优先级多字段排序实现 含空值null特殊排序规则处理

Laravel 多字段自定义优先级排序实现方案

原有代码问题排查

  • 排序优先级颠倒:链式调用sortBy时,后执行的排序规则优先级更高,你的代码优先级为dnf > out_of_time > points_for_distance > points_for_gtc > points_for_time > total,和需求的优先级顺序完全相反。
  • 积分排序方向错误:sortBy默认是升序,会导致积分越低排名越靠前,和你预期的「积分更低的条目排在更靠后位置」相反。
  • 未处理detail_points_for_gtc空值逻辑:原生字段排序无法自定义空值的排序权重。

实现方案

方案1:Laravel 8+ 多字段排序(推荐)

Laravel 8及以上版本支持直接传入排序规则数组,写法简洁直观:

$results = $results->sortBy([
    // 优先级1:完赛排在前面,dnf=false(0) < dnf=true(1),升序排列
    ['dnf', 'asc'],
    // 优先级2:未超时排在前面,out_of_time=false < out_of_time=true,升序排列
    ['out_of_time', 'asc'],
    // 优先级3:总积分高的排在前面,降序排列
    ['total', 'desc'],
    // 优先级4:时间积分高的排在前面,降序排列
    ['points_for_time', 'desc'],
    // 优先级5:秘密时间控制积分高的排在前面,空值沉底
    function ($item, $key) {
        // 自定义空值判断规则,可根据业务调整
        $gtcValue = $item['detail_points_for_gtc']; // 对象格式改为$item->detail_points_for_gtc
        if (is_null($gtcValue) || $gtcValue === [] || $gtcValue === '') {
            // 空值返回极小值,降序时自动排在最后
            return -PHP_INT_MAX;
        }
        // 数组格式取总和,和示例中的points_for_gtc逻辑对齐
        return is_array($gtcValue) ? array_sum($gtcValue) : $gtcValue;
    }, 'desc',
    // 优先级6:行驶距离积分高的排在前面,降序排列
    ['points_for_distance', 'desc'],
]);

方案2:自定义回调排序(兼容所有Laravel版本)

如果使用低版本Laravel,可直接通过sort方法自定义比较逻辑:

$results = $results->sort(function ($a, $b) {
    // 注意:如果是数组格式,将->替换为[]即可,如$a['dnf']
    // 1. 比较完赛状态
    if ($a->dnf != $b->dnf) {
        return $a->dnf ? 1 : -1;
    }
    // 2. 比较超时状态
    if ($a->out_of_time != $b->out_of_time) {
        return $a->out_of_time ? 1 : -1;
    }
    // 3. 比较总积分
    if ($a->total != $b->total) {
        return $b->total <=> $a->total;
    }
    // 4. 比较时间积分
    if ($a->points_for_time != $b->points_for_time) {
        return $b->points_for_time <=> $a->points_for_time;
    }
    // 5. 比较秘密时间控制积分
    $getGtcValue = function ($item) {
        $gtc = $item->detail_points_for_gtc;
        if (is_null($gtc) || $gtc === [] || $gtc === '') {
            return -PHP_INT_MAX;
        }
        return is_array($gtc) ? array_sum($gtc) : $gtc;
    };
    $aGtc = $getGtcValue($a);
    $bGtc = $getGtcValue($b);
    if ($aGtc != $bGtc) {
        return $bGtc <=> $aGtc;
    }
    // 6. 比较行驶距离积分
    return $b->points_for_distance <=> $a->points_for_distance;
});

补充说明

  • 空值判断规则可根据业务调整:如果0属于合法积分值,不要在空值判断中包含0即可。
  • 如果需要调整某个字段的排序方向,只需要把升序/降序标识互换,或者互换<=>运算符两边的变量即可。

内容的提问来源于stack exchange,提问作者Robin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:09:03