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

如何在不移动lock>0行的前提下按score和strtotime排序PHP数组

PHP数组排序:锁定元素固定位置,其余按规则排序

需求明确:

  • 数组中lock值大于0的元素,必须保持原始位置不动
  • 剩余lock=0的元素,先按score从小到大排序;若score相同,再按strtotime从小到大排序

输入数组

$array = [
    ['id' => 7867867, 'lock' => 0, 'score' => 322, 'strtotime' => 16614713],
    ['id' => 7867867, 'lock' => 0, 'score' => 444, 'strtotime' => 16614613],
    ['id' => 7867867, 'lock' => 3, 'score' =>   0, 'strtotime' => 16613713],
    ['id' => 7867867, 'lock' => 0, 'score' =>  11, 'strtotime' => 16612713],
    ['id' => 7867867, 'lock' => 5, 'score' =>   0, 'strtotime' => 16614413],
    ['id' => 7867867, 'lock' => 0, 'score' =>  42, 'strtotime' => 16614113],
    ['id' => 7867867, 'lock' => 0, 'score' =>  22, 'strtotime' => 16614013],
];

现有代码的问题

直接使用usort会让所有元素参与排序,包括锁定元素,导致它们的位置被打乱;另外原代码还错误地用对象语法->访问关联数组,会触发报错:

usort($array, function ($a, $b) {
    if ( $a->score == $b->score ) {  
       return $b->strtotime <=> $a->strtotime; 
    }
    return $b->score <=> $a->score; 
});

期望输出

[
    ['id' => 7867867, 'lock' => 0, 'score' =>  11, 'strtotime' => 16612713],
    ['id' => 7867867, 'lock' => 0, 'score' =>  22, 'strtotime' => 16614013],
    ['id' => 7867867, 'lock' => 3, 'score' =>   0, 'strtotime' => 16613713],
    ['id' => 7867867, 'lock' => 0, 'score' =>  42, 'strtotime' => 16614113],
    ['id' => 7867867, 'lock' => 5, 'score' =>   0, 'strtotime' => 16614413],
    ['id' => 7867867, 'lock' => 0, 'score' => 322, 'strtotime' => 16614713],
    ['id' => 7867867, 'lock' => 0, 'score' => 444, 'strtotime' => 16614613],
]

解决方案

不能直接全量排序,需拆分处理:

  1. 提取所有lock=0的元素,单独按规则排序
  2. 遍历原数组,遇到锁定元素直接保留;遇到未锁定元素,用排序好的列表依次填充

完整代码:

// 1. 提取未锁定元素并按规则排序
$unlocked = array_filter($array, function($item) {
    return $item['lock'] == 0;
});

usort($unlocked, function($a, $b) {
    // 先按score升序,score相同则按strtotime升序
    if ($a['score'] !== $b['score']) {
        return $a['score'] <=> $b['score'];
    }
    return $a['strtotime'] <=> $b['strtotime'];
});

// 重置索引,方便后续逐个取出
$unlocked = array_values($unlocked);
$index = 0;

// 2. 重新构建结果数组
$result = [];
foreach ($array as $item) {
    if ($item['lock'] > 0) {
        // 锁定元素保留原位置
        $result[] = $item;
    } else {
        // 未锁定元素用排序后的列表填充
        $result[] = $unlocked[$index++];
    }
}

// 输出结果
print_r($result);

这段代码会严格保留lock>0元素的原始位置,同时让未锁定元素按规则填充到剩余位置,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:06:52