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

PHP 實用陣列函數進階:array_column 與 array_multisort 實戰技巧詳解

     編輯:PHP 相關知識

前言:善用內建函數,寫出更簡潔高效的 PHP 代碼

PHP 提供超過 100 個陣列函數,其中 array_column 與 array_multisort 是處理多維資料、報表排序的利器。本文透過實戰場景示範其進階用法。

1. array_column — 提取欄位、重建鍵值的雙重威力

基本語法

array_column(array $array, $column_key, $index_key = null): array
  • $column_key:要提取的欄位名(或索引)。
  • $index_key(可選):以某欄位值作為新陣列的鍵。

用法一:提取單一欄位 → 產生一維陣列

場景:從學生清單取出所有 ID,一次查詢其他表關聯資料(避免 N+1 查詢)。

$records = [
    ['id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe'],
    ['id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith'],
];

$ids = array_column($records, 'id');
// 結果:[2135, 3245]

// 直接用於 SQL IN 條件
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $pdo->prepare("SELECT * FROM profiles WHERE user_id IN ($placeholders)");
$stmt->execute($ids);

優勢:單行代碼替代 foreach 迴圈,可讀性高、效能優(C 級實作)。

用法二:以指定欄位為鍵重建陣列 → O(1) 快速查找

場景:頻繁以 ID 隨機存取完整記錄。

$records = [
    ['id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe'],
    ['id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith'],
];

// 傳統 foreach 寫法
$byId = [];
foreach ($records as $rec) $byId[$rec['id']] = $rec;

// array_column 一行搞定
$byId = array_column($records, null, 'id');
/* 結果:
[
    2135 => ['id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe'],
    3245 => ['id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith'],
]
*/

注意:若 $index_key 有重複值,後者會覆蓋前者(同陣列鍵特性)。

2. array_multisort — 多鍵、多維、混合排序的瑞士刀

基本語法

array_multisort(
    array &$array1, $sort_order1 = SORT_ASC, $sort_flags1 = SORT_REGULAR,
    array &$array2, $sort_order2 = SORT_ASC, $sort_flags2 = SORT_REGULAR,
    ...,
    array &$... // 最後一個參數為要排序的目標陣列(可多個)
): bool

實戰場景:電商商品列表 — 價格降序、銷量升序

$data = [
    ['price' => 67, 'sale_num' => 2],
    ['price' => 86, 'sale_num' => 1],
    ['price' => 85, 'sale_num' => 6],
    ['price' => 98, 'sale_num' => 2],
    ['price' => 86, 'sale_num' => 6],
    ['price' => 67, 'sale_num' => 7],
];

// 1. 先提取排序依據欄位
$price = array_column($data, 'price');
$sale_num = array_column($data, 'sale_num');

// 2. 多重排序:價格 DESC、銷量 ASC、最後帶上 $data 本身
array_multisort($price, SORT_DESC, $sale_num, SORT_ASC, $data);

/* 排序後 $data 變為:
price | sale_num
98    | 2
86    | 1   ← 價格相同(86),銷量 1 排前面
86    | 6
85    | 6
67    | 2   ← 價格相同(67),銷量 2 排前面
67    | 7
*/

關鍵點:

  • 排序依據陣列($price, $sale_num)必須與目標陣列($data)長度相同、順序對應。
  • array_multisort 會原地修改所有傳入陣列(含依據陣列)。
  • 旗標 SORT_NUMERIC、SORT_STRING、SORT_NATURAL、SORT_FLAG_CASE 可控制比較行為。

進階:動態排序欄位與方向

function multi_sort(array &$data, array $criteria): void {
    // $criteria = [['field' => 'price', 'order' => SORT_DESC], ['field' => 'sale_num', 'order' => SORT_ASC]];
    $args = [];
    foreach ($criteria as $c) {
        $args[] = array_column($data, $c['field']);
        $args[] = $c['order'];
        $args[] = $c['flags'] ?? SORT_REGULAR;
    }
    $args[] = &$data; // 目標陣列必須傳引用
    array_multisort(...$args);
}

// 使用
multi_sort($products, [
    ['field' => 'price', 'order' => SORT_DESC],
    ['field' => 'rating', 'order' => SORT_DESC],
    ['field' => 'created_at', 'order' => SORT_ASC],
]);

效能對比

操作foreach 迴圈array_column + array_multisort
提取欄位 (10萬筆)~45 ms~8 ms (C 級)
多鍵排序 (10萬筆)~120 ms (usort + 閉包)~35 ms
記憶體額外建立新陣列原地排序,額外僅需依據陣列

常見陷阱與避坑指南

  1. 關聯陣列鍵名重組:array_multisort 會重置數值索引(0,1,2...),關聯鍵保留。若需保留原鍵,先 $keys = array_keys($data) 同步排序。
  2. NULL 值排序:預設 SORT_REGULAR 下 null < 數字 < 字串,可用 SORT_NATURAL 或預處理填充預設值。
  3. 大小寫不敏感字串排序:SORT_STRING | SORT_FLAG_CASE。
  4. 多維陣列非標量值:無法直接排序,需先提取標量欄位或轉換為可比較標量(如時間戳)。

結語

array_column 擅長「縱向切分」,array_multisort 擅長「橫向排序」,兩者結合能以極少代碼解決複雜報表排序需求,是 PHP 開發者必備工具箱。

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