首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 陣列排序大全:一維與多維陣列、sort/asort/ksort、array_multisort、自訂比較函式完整指南

     編輯:PHP 相關知識

前言:陣列排序是資料處理的核心技能

PHP 提供豐富的陣列排序函式,針對一維、多維、關聯式陣列都有對應方案。選對函式能讓程式碼更簡潔、效能更優異。本文系統整理所有排序函式差異、適用場景與實戰範例。

一維陣列排序函式完整對照

函式排序依據鍵名保留順序適用場景
sort()值❌ 重設為 0..n升序數值索引陣列,不在乎原鍵名
rsort()值❌ 重設為 0..n降序同上,需降序
asort()值✅ 保留關聯升序關聯陣列依值排序
arsort()值✅ 保留關聯降序同上,需降序
ksort()鍵名✅ 保留關聯升序依鍵名字母/數字排序
krsort()鍵名✅ 保留關聯降序同上,需降序

關鍵差異示範

<?php
$a = ["a" => 10, 0 => 5, "b" => 1];

sort($a);    // [0=>1, 1=>5, 2=>10]  鍵名 'a','b' 消失
asort($a);   // ["b"=>1, 0=>5, "a"=>10] 保留鍵名
ksort($a);   // [0=>5, "a"=>10, "b"=>1]  依鍵名排序
?>

自訂比較函式排序

函式比較對象鍵名保留
uasort()值✅
uksort()鍵名✅
usort()值❌ 重設索引

比較函式規範 (PHP 7+ 太空船運算子)

<?php
// 回傳負數:$a 排前面;0:不變;正數:$a 排後面
function cmp($a, $b) {
    return $a <=> $b; // 升序
    // return $b <=> $a; // 降序
}

// 多欄位排序
function cmpMulti($a, $b) {
    // 先比 age 升序,再比 name 降序
    return [$a['age'], -strcmp($a['name'], $b['name'])] <=> [$b['age'], -strcmp($b['name'], $a['name'])];
    // 更簡潔寫法 (PHP 7+):
    return [$a['age'], $b['name']] <=> [$b['age'], $a['name']]; // 注意:第二欄位若要降序需技巧處理
}
?>

實戰:選單依 order 欄位排序

<?php
$menu = [
    'index'    => ['name' => '首頁',       'order' => 3],
    'intro'    => ['name' => '企業概況',   'order' => 2],
    'news'     => ['name' => '新聞動態',   'order' => 1],
    'product'  => ['name' => '產品中心',   'order' => 4],
    'contact'  => ['name' => '聯絡我們',   'order' => 5],
];

uasort($menu, fn($a, $b) => $a['order'] <=> $b['order']);
// 結果順序:news(1) → intro(2) → index(3) → product(4) → contact(5)
?>

多維陣列排序:array_multisort 進階應用

array_multisort() 可同時排序多個陣列,或依多個欄位排序多維陣列,類似 SQL ORDER BY col1 DESC, col2 ASC。

基本機制:平行陣列同步排序

<?php
$a = [100, 80, 50, 10, 0];
$b = ["c", "f", "q", "e", "z"];

array_multisort($a, $b);
// $a: [0, 10, 50, 80, 100]
// $b: ["z", "e", "q", "f", "c"]  // 原第5個 'z' 移到第1位
?>

多維陣列實戰:提取欄位陣列再排序

<?php
$records = [
    ["age" => 20, "name" => "li"],
    ["age" => 21, "name" => "ai"],
    ["age" => 20, "name" => "ci"],
    ["age" => 22, "name" => "di"],
];

// 步驟 1:提取排序欄位
$age = array_column($records, 'age');
$name = array_column($records, 'name');

// 步驟 2:排序 (最後一個參數是目標陣列)
array_multisort($age, SORT_NUMERIC, SORT_DESC,
                $name, SORT_STRING, SORT_ASC,
                $records);

/* 結果:
[0] => age:22, name:di
[1] => age:21, name:ai
[2] => age:20, name:ci  (ci < li 字典序)
[3] => age:20, name:li
*/
?>

現代寫法:array_column 內聯 (PHP 5.5+)

<?php
array_multisort(
    array_column($records, 'age'),  SORT_DESC,
    array_column($records, 'name'), SORT_ASC,
    $records
);
?>

排序旗標完整說明

旗標說明
SORT_ASC升序 (預設)
SORT_DESC降序
SORT_REGULAR一般比較 (預設)
SORT_NUMERIC數值比較
SORT_STRING字串比較
SORT_LOCALE_STRING依 locale 字串比較 (需 setlocale())
SORT_NATURAL自然排序 ("img2" < "img10")
SORT_FLAG_CASE不區分大小寫 (配合 SORT_STRING)

完整參數順序規則


array_multisort(
    array1, [sort_flags1], [sort_order1],
    array2, [sort_flags2], [sort_order2],
    ...,
    target_array  // 必須是最後一個參數
)

進階實戰案例

案例一:電商商品排序 (價格、銷量、評分、上架時間)

<?php
$products = [
    ['id'=>1, 'price'=>299, 'sales'=>150, 'rating'=>4.5, 'created'=>'2024-01-15'],
    ['id'=>2, 'price'=>199, 'sales'=>300, 'rating'=>4.2, 'created'=>'2024-02-10'],
    ['id'=>3, 'price'=>299, 'sales'=>150, 'rating'=>4.8, 'created'=>'2024-01-20'],
    ['id'=>4, 'price'=>399, 'sales'=>80,  'rating'=>4.9, 'created'=>'2024-03-01'],
];

// 預設排序:銷量降序 → 評分降序 → 價格升序 → 上架時間升序
array_multisort(
    array_column($products, 'sales'),  SORT_NUMERIC, SORT_DESC,
    array_column($products, 'rating'), SORT_NUMERIC, SORT_DESC,
    array_column($products, 'price'),  SORT_NUMERIC, SORT_ASC,
    array_column($products, 'created'),SORT_STRING,  SORT_ASC,
    $products
);
?>

案例二:中文姓名筆畫/拼音排序

<?php
$names = ['張三', '李四', '王五', '趙六', '陳七'];

// 使用 Collator (intl 擴充套件) 正確中文排序
$collator = new Collator('zh_TW');
$collator->setStrength(Collator::TERTIARY); // 區分聲調

usort($names, [$collator, 'compare']);
// 或自然排序旗標 (PHP 5.4+)
sort($names, SORT_NATURAL | SORT_FLAG_CASE);
?>

效能考量與替代方案

場景推薦方案理由
資料庫查詢結果SQL ORDER BY索引優化、避免記憶體排序
小型陣列 (< 10k)PHP 內建排序簡單直接、效能足夠
大型陣列 (> 100k)分批處理/資料庫排序記憶體與 CPU 考量
複雜物件排序usort + 太空船運算子邏輯封裝在比較函式
需穩定排序PHP 8.0+ 內建穩定相同值保持原相對順序

PHP 8.0+ 穩定排序保證

PHP 8.0 起所有排序函式保證 穩定排序:相同比較值的元素,相對順序不變。舊版本 sort()/usort() 為不穩定排序。

常見陷阱避坑指南

陷阱現象解決
sort() 導致關聯鍵遺失字串鍵名消失改用 asort()/ksort()
array_multisort 陣列長度不一Warning: Array sizes are inconsistent確保所有排序陣列長度相同
旗標順序錯誤排序結果不如預期嚴格遵循:陣列、類型旗標、順序旗標
中文排序亂序非預期順序使用 Collator 或 SORT_LOCALE_STRING + setlocale()
比較函式回傳非整數PHP 7+ TypeError使用 <=> 或確保回傳 -1/0/1
float 精度導致排序異常0.1+0.2 != 0.3 影響順序乘以倍數轉整數比較或用 bcmath

總結:選對工具的決策樹

需要排序?
├─ 一維陣列
│   ├─ 依值排序,不在乎鍵名 → sort() / rsort()
│   ├─ 依值排序,保留鍵名 → asort() / arsort()
│   ├─ 依鍵名排序 → ksort() / krsort()
│   └─ 自訂邏輯 → uasort() / uksort() / usort()
└─ 多維陣列 / 多欄位排序
    ├─ 簡單多欄位 → array_multisort() + array_column()
    ├─ 複雜物件/邏輯 → usort() + 太空船運算子
    └─ 超大資料集 → 資料庫 ORDER BY / 外部排序

掌握這些排序工具與選擇邏輯,能讓資料處理程式碼更專業、更高效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved