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

PHP 多維陣列扁平化為一維的三種遞歸實現:foreach、for、while 深度解析

     編輯:PHP 相關知識

將任意深度的多維陣列「拍平」為一維陣列是常見需求。本文對比三種遞歸寫法——foreach(通用)、for(僅數字索引)、while + each()(指針操作),分析適用場景與效能差異。

方法一:foreach 遞歸(推薦通用)

function arr_foreach($arr) {
    static $tmp = [];
    if (!is_array($arr)) return false;

    foreach ($arr as $val) {
        if (is_array($val)) {
            arr_foreach($val);
        } else {
            $tmp[] = $val;
        }
    }
    return $tmp;
}

// 測試
$a = [1, 2 => [3, 4 => [5, 6]], 7];
print_r(arr_foreach($a));
/*
Array
(
    [0] => 1
    [1] => 3
    [2] => 5
    [3] => 6
    [4] => 7
)
*/

優點:支援關聯陣列與數字索引混合、語義清晰、PHP 所有版本相容。
缺點:靜態變數導致非線程安全、多次呼叫需手動重置。

方法二:for 循環遞歸(僅數字索引)

function arr_for($arr) {
    static $tmp = [];
    for ($i = 0; $i < count($arr); $i++) {
        if (is_array($arr[$i])) {
            arr_for($arr[$i]);
        } else {
            $tmp[] = $arr[$i];
        }
    }
    return $tmp;
}

$a = [1, [3, [5, 6]], 7];
print_r(arr_for($a)); // 同樣輸出 [1,3,5,6,7]

限制:count($arr) 與 $arr[$i] 僅適用於連續數字鍵,關聯鍵會被跳過或報錯。

方法三:while + each() 指針遞歸(進階)

/**
 * 多維轉一維(指針操作版)
 * @param array $arr
 * @return array
 */
function ArrMd2Ud($arr) {
    // 以第一個元素為基準容器(引用賦值)
    $ar_room = &$arr[key($arr)];
    if (!is_array($ar_room)) $ar_room = [$ar_room];

    next($arr); // 指針下移

    while (list($k, $v) = each($arr)) {
        // 遞歸處理子陣列,非陣列包裝為陣列
        $v = is_array($v) ? call_user_func(__FUNCTION__, $v) : [$v];
        // 遞歸合併
        $ar_room = array_merge_recursive($ar_room, $v);
        // 釋放已處理元素
        unset($arr[$k]);
    }
    return $ar_room;
}

$arr = [1, 2, 3 => [1, 2, 'ar' => [1, 2 => ['a', 'b']]], ['ar' => [3, 4]]];
print_r(ArrMd2Ud($arr));
/*
Array
(
    [0] => 1
    [1] => 2
    [2] => 1
    [3] => 2
    [4] => 1
    [5] => a
    [6] => b
    [7] => 3
    [8] => 4
)
*/

特點:利用引用與指針原地操作,記憶體效率較高;但 each() 在 PHP 7.2+ 棄用、PHP 8.0+ 移除,現代專案不建議使用。

現代最佳實踐:array_walk_recursive(PHP 5+)

function flatten_modern($arr) {
    $result = [];
    array_walk_recursive($arr, function($val) use (&$result) {
        $result[] = $val;
    });
    return $result;
}
  • 內建函數、C 層實現、效能最優。
  • 自動忽略鍵名,僅收集值。
  • 無靜態變數汙染、線程安全。

對比總結表

方法支援關聯鍵PHP 版本效能推薦度
foreach + static是所有中★★★☆☆
for 循環否所有中★★☆☆☆
while + each()是<7.2較高★☆☆☆☆ (棄用)
array_walk_recursive是5.0+最高★★★★★

選型建議

  • 新專案:直接用 array_walk_recursive 或 RecursiveArrayIterator + RecursiveIteratorIterator。
  • 舊代碼維護:理解上述三種遞歸邏輯,重構時替換為現代寫法。
  • 需保留鍵名路徑:需自行實現帶路徑前綴的扁平化(如 user.address.city)。

扁平化看似簡單,選對工具能省下大量維護成本,現代 PHP 開發者應優先採用內建遞歸迭代器。

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