PHP 数组排序
The sort family, key-preserving sorts, and custom comparators.
Key Points`sort` reindexes and drops keys; `asort` / `ksort` preserve key association.
排序函数总览
| Function | Sorts by | Keeps keys | Order |
|---|---|---|---|
| sort | 值 | 否 | 升序 |
| rsort | 值 | 否 | 降序 |
| asort | 值 | 是 | 升序 |
| arsort | 值 | 是 | 降序 |
| ksort | 键 | 是 | 升序 |
| krsort | 键 | 是 | 降序 |
| usort | 自定义 | 否 | 自定义 |
| uasort | 自定义 | 是 | 自定义 |
| uksort | 键 + 自定义 | 是 | 自定义 |
基础排序
PHP
<?php
$nums = [3, 1, 4, 1, 5];
sort($nums);
print_r($nums);
rsort($nums);
print_r($nums);Output
Array
(
[0] => 1
[1] => 1
[2] => 3
[3] => 4
[4] => 5
)
Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 1
[4] => 1
)sort() mutates in place and returns bool, not the array. $sorted = sort($arr); gives true while $arr is already reordered.保留键的排序
For associative arrays sort values with asort; otherwise keys are lost and $scores["Tom"] no longer resolves.
PHP
<?php
$scores = ["Tom" => 88, "Amy" => 95, "Bob" => 72];
asort($scores);
print_r($scores);
ksort($scores);
print_r($scores);Output
Array
(
[Amy] => 95
[Tom] => 88
[Bob] => 72
)
Array
(
[Amy] => 95
[Bob] => 72
[Tom] => 88
)字符串排序的坑
PHP
<?php
$words = ["Banana", "apple", "Cherry"];
sort($words);
print_r($words);
sort($words, SORT_FLAG_CASE | SORT_STRING);
print_r($words);Output
Array
(
[0] => Banana
[1] => Cherry
[2] => apple
)
Array
(
[0] => apple
[1] => Banana
[2] => Cherry
)The default is byte order, so uppercase sorts before lowercase. Pass SORT_FLAG_CASE | SORT_STRING to ignore case.
Byte comparison is meaningless for Chinese. Use
collator (intl extension) or build your own pinyin map.自定义比较
PHP
<?php
$nums = [3, 1, 4, 1, 5];
usort($nums, fn($a, $b) => $b <=> $a);
print_r($nums);
$users = [
["name" => "Tom", "age" => 30],
["name" => "Amy", "age" => 25],
["name" => "Bob", "age" => 35],
];
usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);
foreach ($users as $u) {
echo $u["name"] . ":" . $u["age"] . "\n";
}
// 多级排序:先按年龄升序,年龄相同按名字降序
usort($users, fn($a, $b) => [$a["age"], $b["name"]] <=> [$b["age"], $a["name"]]);
print_r(array_column($users, "name"));Output
Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 1
[4] => 1
)
Amy:25
Tom:30
Bob:35
Array
(
[0] => Amy
[1] => Tom
[2] => Bob
)A comparator must return negative / zero / positive — <=> is the cleanest. Returning a boolean is unreliable in PHP 8.
自然排序
sort puts file10 before file2. Use natsort / natcasesort for filenames and version strings.
PHP
<?php
$files = ["file10.txt", "file2.txt", "file1.txt"];
sort($files);
print_r($files);
natsort($files);
print_r($files);Output
Array
(
[0] => file1.txt
[1] => file10.txt
[2] => file2.txt
)
Array
(
[2] => file1.txt
[0] => file2.txt
[1] => file10.txt
)natsort preserves keys, so the key order looks scrambled. Wrap it in array_values() if you need clean indexes.排序函数总览
| 函数 | 排序依据 | 保留键 | 方向 |
|---|---|---|---|
| sort | 值 | 否 | 升序 |
| rsort | 值 | 否 | 降序 |
| asort | 值 | 是 | 升序 |
| arsort | 值 | 是 | 降序 |
| ksort | 键 | 是 | 升序 |
| krsort | 键 | 是 | 降序 |
| usort | 自定义 | 否 | 自定义 |
| uasort | 自定义 | 是 | 自定义 |
| uksort | 键 + 自定义 | 是 | 自定义 |
基础排序
PHP
<?php
$nums = [3, 1, 4, 1, 5];
sort($nums);
print_r($nums);
rsort($nums);
print_r($nums);Output
Array
(
[0] => 1
[1] => 1
[2] => 3
[3] => 4
[4] => 5
)
Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 1
[4] => 1
)sort() 是原地修改,返回值是 bool 不是数组。写成 $sorted = sort($arr); 会得到 true,原数组已被改。保留键的排序
关联数组按值排序必须用 asort,否则键会被丢掉,$scores["Tom"] 就再也找不到了。
PHP
<?php
$scores = ["Tom" => 88, "Amy" => 95, "Bob" => 72];
asort($scores);
print_r($scores);
ksort($scores);
print_r($scores);Output
Array
(
[Amy] => 95
[Tom] => 88
[Bob] => 72
)
Array
(
[Amy] => 95
[Bob] => 72
[Tom] => 88
)字符串排序的坑
PHP
<?php
$words = ["Banana", "apple", "Cherry"];
sort($words);
print_r($words);
sort($words, SORT_FLAG_CASE | SORT_STRING);
print_r($words);Output
Array
(
[0] => Banana
[1] => Cherry
[2] => apple
)
Array
(
[0] => apple
[1] => Banana
[2] => Cherry
)默认按字节比较,大写字母(A-Z,65-90)排在小写(a-z,97-122)前面。要忽略大小写,传 SORT_FLAG_CASE | SORT_STRING。
中文排序用默认的字节比较结果基本没意义。需要按拼音排序得用
collator(intl 扩展)或自己建映射表。自定义比较
PHP
<?php
$nums = [3, 1, 4, 1, 5];
usort($nums, fn($a, $b) => $b <=> $a);
print_r($nums);
$users = [
["name" => "Tom", "age" => 30],
["name" => "Amy", "age" => 25],
["name" => "Bob", "age" => 35],
];
usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);
foreach ($users as $u) {
echo $u["name"] . ":" . $u["age"] . "\n";
}
// 多级排序:先按年龄升序,年龄相同按名字降序
usort($users, fn($a, $b) => [$a["age"], $b["name"]] <=> [$b["age"], $a["name"]]);
print_r(array_column($users, "name"));Output
Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 1
[4] => 1
)
Amy:25
Tom:30
Bob:35
Array
(
[0] => Amy
[1] => Tom
[2] => Bob
)比较函数必须返回负数 / 0 / 正数,用 <=> 最省事。返回布尔值在 PHP 8 里行为不可靠。
自然排序
sort 会把 file10 排在 file2 前面(按字符比)。文件名、版本号要用 natsort / natcasesort。
PHP
<?php
$files = ["file10.txt", "file2.txt", "file1.txt"];
sort($files);
print_r($files);
natsort($files);
print_r($files);Output
Array
(
[0] => file1.txt
[1] => file10.txt
[2] => file2.txt
)
Array
(
[2] => file1.txt
[0] => file2.txt
[1] => file10.txt
)natsort 保留键,所以结果里的键顺序是乱的。要顺序整齐就再套一层 array_values()。