排序函數快速比較表
| 函數 | 排序依據 | 鍵名保留 | 順序 | 適用場景 |
sort() | 值 | 否 (重建 0..n) | 升冪 | 索引陣列單純排序 |
rsort() | 值 | 否 | 降冪 | 索引陣列反向排序 |
asort() | 值 | 是 | 升冪 | 關聯陣列按值排序保留鍵值對應 |
arsort() | 值 | 是 | 降冪 | 關聯陣列按值反向排序 |
ksort() | 鍵名 | 是 | 升冪 | 關聯陣列按鍵名排序 |
krsort() | 鍵名 | 是 | 降冪 | 關聯陣列按鍵名反向排序 |
natsort() | 值 (自然排序) | 是 | 升冪 | 字母數字混合自然順序 (img2 < img10) |
natcasesort() | 值 (自然排序) | 是 | 升冪 | 不分大小寫自然排序 |
usort() | 自訂比較函數 | 否 | 自訂 | 複雜邏輯、多欄位、物件排序 |
uasort() | 自訂比較函數 | 是 | 自訂 | 關聯陣列自訂排序保留鍵名 |
uksort() | 自訂比較鍵名 | 是 | 自訂 | 關聯陣列按鍵名自訂排序 |
核心差異範例
1. sort() vs asort() - 鍵名保留
$arr = ['c' => 3, 'a' => 1, 'b' => 2];
sort($arr); // [0=>1, 1=>2, 2=>3] 鍵名重建
asort($arr); // ['a'=>1, 'b'=>2, 'c'=>3] 保留鍵名
2. 自然排序 natsort() 神奇效果
$files = ['img1.png', 'img10.png', 'img2.png', 'img20.png'];
sort($files); // ['img1.png', 'img10.png', 'img2.png', 'img20.png'] (字典序)
natsort($files); // ['img1.png', 'img2.png', 'img10.png', 'img20.png'] (自然序)
3. 多維陣列排序:array_multisort()
$users = [
['name'=>'John', 'age'=>25, 'score'=>90],
['name'=>'Jane', 'age'=>22, 'score'=>95],
['name'=>'Bob', 'age'=>25, 'score'=>85],
];
// 年齡升冪,同齡分數降冪
$age = array_column($users, 'age');
$score = array_column($users, 'score');
array_multisort($age, SORT_ASC, $score, SORT_DESC, $users);
// 結果: Jane(22,95), John(25,90), Bob(25,85)
4. 物件排序:usort() + 箭頭函數 (PHP 7.4+)
class Product {
public $name, $price;
public function __construct($n, $p) { $this->name=$n; $this->price=$p; }
}
$products = [
new Product('A', 100),
new Product('B', 50),
new Product('C', 150),
];
usort($products, fn($a, $b) => $a->price <=> $b->price); // 太空船運算子
// 結果: B(50), A(100), C(150)
效能與記憶體注意事項
- 所有排序函數**就地修改**原陣列,回傳 `bool` 非新陣列
- 大陣列排序消耗記憶體,考慮分批、資料庫 `ORDER BY`
- `usort` 等自訂比較函數較慢 (PHP 用戶空間呼叫開銷)
- PHP 8.0+ 排序算法改進 (Timsort),近乎有序資料極快
常見錯誤
// 錯誤:以為回傳新陣列
$sorted = sort($arr); // $sorted = true, $arr 已被修改
// 正確:需要副本時先複製
$sorted = $arr;
sort($sorted);
選擇指南
- 索引陣列、不需鍵名 → `sort()` / `rsort()`
- 關聯陣列、按值排序 → `asort()` / `arsort()`
- 關聯陣列、按鍵排序 → `ksort()` / `krsort()`
- 檔名、版本號等字母數字混合 → `natsort()` / `natcasesort()`
- 複雜邏輯、多欄位、物件 → `usort()` / `uasort()` / `uksort()`
- 多維陣列多欄位 → `array_multisort()`