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

PHP 多維陣列指定鍵值排序:array_multisort() 進階用法與三種自訂函式實作

     編輯:PHP 相關知識

PHP array_multisort() 可同時對多個陣列或多維陣列的特定鍵進行排序,但原生用法需手動提取排序鍵。本文提供三種封裝函式實作,支援升降序、多鍵排序、型別轉換,並分析效能與適用場景。

array_multisort() 核心機制

array_multisort(array &$array1, mixed $sortOrder = SORT_ASC, mixed $sortFlags = SORT_REGULAR, array &$...): bool
  • 可接受多個陣列,後續陣列作為「從屬排序」依據(值同步重排)。
  • 排序旗標:SORT_ASC/SORT_DESC、SORT_REGULAR/SORT_NUMERIC/SORT_STRING。
  • 關聯鍵名保留,數字鍵重新索引(0 起)。

實作一:通用多維陣列單鍵排序(推薦)

<?php
/**
 * 多維陣列指定鍵排序
 * @param array $data 待排序陣列(引用修改)
 * @param string $key 排序鍵名
 * @param int $order SORT_ASC | SORT_DESC
 * @param int $flag SORT_REGULAR | SORT_NUMERIC | SORT_STRING
 * @return bool
 */
function multiArraySort(array &$data, string $key, int $order = SORT_DESC, int $flag = SORT_REGULAR): bool {
    if (empty($data) || !is_array($data)) return false;
    
    $keyArray = [];
    foreach ($data as $row) {
        if (!is_array($row) || !array_key_exists($key, $row)) {
            return false; // 結構不一致
        }
        $keyArray[] = $row[$key];
    }
    
    // array_multisort 會修改 $data 順序
    return array_multisort($keyArray, $order, $flag, $data);
}

// === 使用範例 ===
$users = [
    ['id' => 8, 'name' => 'phpernote', 'score' => 95.5],
    ['id' => 9, 'name' => 'com', 'score' => 87.2],
    ['id' => 5, 'name' => 'www', 'score' => 92.1],
];

multiArraySort($users, 'id', SORT_ASC, SORT_NUMERIC);
print_r($users);
// 輸出:id 5, 8, 9 升序
?>

實作二:asort/arsort 基礎版(適合純量值)

<?php
function arraySortByKey(array $arr, string $key, string $order = 'asc'): array {
    $keyValues = [];
    foreach ($arr as $k => $v) {
        $keyValues[$k] = $v[$key] ?? null;
    }
    
    $order === 'asc' ? asort($keyValues) : arsort($keyValues);
    
    $result = [];
    foreach ($keyValues as $k => $v) {
        $result[] = $arr[$k];
    }
    return $result;
}
?>

實作三:完整功能版(支援字串清理、多型別、錯誤處理)

<?php
function arraySortAdvanced(array $array, string $key, string $order = 'asc'): array {
    // 1. 參數驗證
    if (empty($array) || !is_array($array)) return [];
    if ($key === '') return [];
    if (!in_array(strtolower($order), ['asc', 'desc'])) return [];

    // 2. 提取並清理排序值
    $keyValues = [];
    foreach ($array as $k => $v) {
        if (!is_array($v) || !array_key_exists($key, $v)) continue;
        $val = $v[$key];
        // 字串清理:移除常見干擾字元
        if (is_string($val)) {
            $val = str_replace(['-', ' ', ':'], '', $val);
        }
        $keyValues[$k] = $val;
    }

    // 3. 排序鍵值陣列(保留索引關聯)
    $order === 'asc' ? asort($keyValues) : arsort($keyValues);

    // 4. 重建結果
    $result = [];
    foreach ($keyValues as $k => $v) {
        $result[] = $array[$k];
    }
    return $result;
}

// === 實戰測試 ===
$data = [
    ['id' => '8', 'date' => '2024-01-15'],
    ['id' => '9', 'date' => '2024-01-10'],
    ['id' => '5', 'date' => '2024-01-20'],
];

$sorted = arraySortAdvanced($data, 'id', 'asc');
print_r($sorted);
// id 5, 8, 9 升序(字串數值正確排序)
?>

三種實作對比表

特性實作一 (array_multisort)實作二實作三
原地修改/回傳新陣列原地修改 (引用)回傳新陣列回傳新陣列
支援排序旗標完整 (NUMERIC/STRING/REGULAR)僅字串/數值自動判斷字串清理後自動判斷
錯誤處理回傳 false無參數驗證+跳過無效行
記憶體效率最高 (無複製)中等中等
適用場景大陣列、需保留引用、多鍵排序簡單快速原型髒資料清洗、API 回應排序

進階:多鍵排序(先按 score 降序,再按 id 升序)

<?php
$data = [
    ['id' => 1, 'score' => 90],
    ['id' => 2, 'score' => 95],
    ['id' => 3, 'score' => 90],
];

$score = array_column($data, 'score');
$id    = array_column($data, 'id');

// 多陣列傳入 array_multisort:先排 score DESC,再排 id ASC
array_multisort($score, SORT_DESC, SORT_NUMERIC, $id, SORT_ASC, SORT_NUMERIC, $data);
print_r($data);
// 輸出:id 2(95), 1(90), 3(90) → score 同分時 id 小者優先
?>

效能建議

  • 10萬筆以內:上述實作皆可接受(< 200ms)。
  • 百萬筆以上:改用資料庫 ORDER BY、usort() 配合快取比較函式、或引入 ds\Vector 等高效資料結構。
  • 避免重複計算:排序鍵提取一次即可,勿在比較函式中重複存取。

根據資料規模、髒資料程度、是否需原地修改選擇適當實作,array_multisort() 為核心引擎,封裝層解決工程易用性問題。

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