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

PHP 多維陣列依指定鍵值分組合併:遞歸實現相同字段值聚合

     編輯:PHP 相關知識

PHP 多維陣列依指定鍵值分組合併演算法

應用場景

將多維陣列中某欄位(如 category_id、user_id)值相同的元素聚合為子陣列,常用於:

  • 資料庫查詢結果重組(如訂單按用戶分組)
  • 報表資料預處理
  • API 回傳格式轉換

遞歸分組函式

<?php
/**
 * 依指定鍵值將多維陣列分組合併
 *
 * @param array  $array   來源陣列
 * @param mixed  $start   當前分組的基準鍵值(首次呼叫傳入 $array[0][$key])
 * @param string $key     分組依據的鍵名
 * @param string $newkey  合併後子陣列的鍵名(預設同 $key)
 * @return array 分組後的關聯陣列 [鍵值 => [元素1, 元素2, ...]]
 */
function combine_same_val($array, $start, $key, $newkey = null) {
    static $result = [];
    $newkey = $newkey ?? $key;

    foreach ($array as $k => $v) {
        if (!isset($v[$key])) continue; // 防禦性檢查
        if ($v[$key] == $start) {
            $result[$v[$newkey]][] = $v;
            unset($array[$k]);
        }
    }

    // 重新索引並遞歸處理剩餘元素
    if (count($array) > 0) {
        $array = array_values($array); // 重置索引
        combine_same_val($array, $array[0][$key], $key, $newkey);
    }

    return $result;
}
?>

使用範例

<?php
$data = [
    ['id' => 1, 'category' => 'fruit', 'name' => 'Apple',  'price' => 50],
    ['id' => 2, 'category' => 'fruit', 'name' => 'Banana', 'price' => 30],
    ['id' => 3, 'category' => 'veg',   'name' => 'Carrot', 'price' => 20],
    ['id' => 4, 'category' => 'fruit', 'name' => 'Orange', 'price' => 40],
    ['id' => 5, 'category' => 'veg',   'name' => 'Spinach','price' => 25],
];

$grouped = combine_same_val($data, $data[0]['category'], 'category');
print_r($grouped);

/* 輸出:
Array
(
    [fruit] => Array
        (
            [0] => Array ( [id]=>1 [category]=>fruit [name]=>Apple  [price]=>50 )
            [1] => Array ( [id]=>2 [category]=>fruit [name]=>Banana [price]=>30 )
            [2] => Array ( [id]=>4 [category]=>fruit [name]=>Orange [price]=>40 )
        )
    [veg] => Array
        (
            [0] => Array ( [id]=>3 [category]=>veg [name]=>Carrot  [price]=>20 )
            [1] => Array ( [id]=>5 [category]=>veg [name]=>Spinach [price]=>25 )
        )
)
*/
?>

演算法分析

指標表現
時間複雜度O(n²) —— 每次遞歸遍歷剩餘陣列
空間複雜度O(n) —— 靜態變數累積結果
適用規模中小型陣列(< 10,000 筆)
穩定性保持原陣列相對順序

效能優化版:單次遍歷(O(n))

<?php
function group_by_key_iterative($array, $key, $newkey = null) {
    $newkey = $newkey ?? $key;
    $result = [];
    foreach ($array as $item) {
        if (!isset($item[$key])) continue;
        $groupKey = $item[$newkey];
        $result[$groupKey][] = $item;
    }
    return $result;
}
// 使用方式相同,效能大幅提升
$grouped = group_by_key_iterative($data, 'category');
?>

現代 PHP 寫法(PHP 5.5+)

<?php
// array_column + array_reduce 一行搞定
$grouped = array_reduce($data, function($carry, $item) {
    $carry[$item['category']][] = $item;
    return $carry;
}, []);

// 或使用 Laravel Collection(若有引入)
// collect($data)->groupBy('category')->toArray();
?>

常見陷阱與防禦

  • 鍵名不存在:加入 isset($v[$key]) 判斷
  • 靜態變數殘留:遞歸函式多次呼叫需手動重置 $result = [] 或改用非靜態版本
  • 大量資料記憶體:考慮 Generator 分批處理或資料庫層面 GROUP BY
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved