在PHP中处理数组排序时,普通排序函数会重新生成连续的数字索引,当我们需要保留数组原有的键名尤其是非连续数字索引或字符串键名时,就需要使用特定的排序函数来实现。

常见的会重置索引的排序函数
首先我们需要了解哪些排序函数会直接重置数组索引,避免误用。比如sort()函数会对数组进行升序排序,并且会重置数字索引,字符串键名会被忽略并重新生成数字索引。
<?php $arr = [3 => 'a', 1 => 'b', 2 => 'c']; sort($arr); print_r($arr); // 输出结果:Array ( [0] => a [1] => b [2] => c ),原索引3、1、2全部丢失 ?>
保持索引的排序函数
1. asort() 对值排序保持索引关联
asort()函数会对数组的值进行升序排序,同时保留原有的键名和索引的关联关系,适合需要按值排序但又不能丢失原索引的场景。
<?php $arr = [3 => 'c', 1 => 'a', 2 => 'b']; asort($arr); print_r($arr); // 输出结果:Array ( [1] => a [2] => b [3] => c ),原索引全部保留 ?>
2. arsort() 对值降序排序保持索引
如果需要按值降序排序并保留索引,可以使用arsort()函数,它的用法和asort()类似,只是排序方向相反。
<?php $arr = [3 => 'a', 1 => 'c', 2 => 'b']; arsort($arr); print_r($arr); // 输出结果:Array ( [1] => c [2] => b [3] => a ),原索引保留 ?>
3. ksort() 对键名排序保持索引
当我们需要按照数组的键名进行升序排序,同时保留键名和值的对应关系时,可以使用ksort()函数。
<?php $arr = [3 => 'a', 1 => 'b', 2 => 'c']; ksort($arr); print_r($arr); // 输出结果:Array ( [1] => b [2] => c [3] => a ),按键名1、2、3排序,索引保留 ?>
4. krsort() 对键名降序排序保持索引
对应键名降序排序的场景,使用krsort()函数即可,同样会保留原有的键值对应关系。
<?php $arr = [3 => 'a', 1 => 'b', 2 => 'c']; krsort($arr); print_r($arr); // 输出结果:Array ( [3] => a [2] => c [1] => b ),按键名3、2、1降序排序 ?>
自定义排序保持索引
如果需要按照自定义的规则进行排序,同时保留原索引,可以使用uasort()函数,它允许我们传入自定义的回调函数定义排序规则,并且会保持索引关联。
<?php
$arr = [3 => 10, 1 => 5, 2 => 8];
// 自定义规则:值大的排在前面
uasort($arr, function($a, $b) {
if ($a == $b) {
return 0;
}
return $a > $b ? -1 : 1;
});
print_r($arr);
// 输出结果:Array ( [3] => 10 [2] => 8 [1] => 5 ),原索引保留
?>
不同函数适用场景对比
我们可以通过下表快速选择适合自己场景的排序函数:
| 函数名 | 排序依据 | 排序方向 | 是否保持索引 |
|---|---|---|---|
| sort() | 值 | 升序 | 否 |
| asort() | 值 | 升序 | 是 |
| arsort() | 值 | 降序 | 是 |
| ksort() | 键名 | 升序 | 是 |
| krsort() | 键名 | 降序 | 是 |
| uasort() | 自定义值规则 | 自定义 | 是 |
注意事项
- 上述保持索引的排序函数仅对数组原有的键名生效,排序后不会生成新的数字索引覆盖原有键名。
- 如果数组原有键名是连续的数字索引,使用
asort()等函数排序后,虽然索引还是原来的数字,但顺序已经按照值的要求调整了。 - 如果需要对多维数组的某个字段排序并保持原索引,可以结合
uasort()函数,在回调函数中取出对应字段进行比较即可。