array_reduce 多值化一

pardon110發表於2019-08-11

array_reduce 常出現在框架處理中介軟體部分,本文淺析其原理。

原型

array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed
callback ( mixed $carry , mixed $item ) : mixed
  • 引數
    • carry 攜帶上次迭代裡的值; 如果本次迭代是第一次,那麼這個值是 initial
    • item 攜帶了本次迭代的值
    • initial 如果指定了可選引數 initial,該引數將在處理開始前使用,或者當處理結束,陣列為空時的最後一個結果
  • 返回值
    • 返回 initial 引數,array_reduce() 返回 NULL
    • 5.3.0+ 修改 initial 型別,允許傳入 mixed,之前只能是 integer

原理

  • array_reduce 函式內部實現機制,用下面的程式碼表示更形象
    function array_reduce2($array, $callback, $initial=null){
        $acc = $initial;
        foreach($array as $a)
            $acc = $callback($acc, $a);
        return $acc;
    }

   array_reduce2([2,4],function($carry,$x){
        return  $carry+$x;
    });  // 6

進階

  • array_reduce 可用多個可迭代序列元素有序疊加處理初始值,而它的返回結果型別,通常由初始 initial 型別決定
  • 當陣列序列元素為一個個函式(可呼叫物件 callable,可為方法,回撥例項,php支援的動靜方法呼叫方式...), 則能實現對特定變數進行一系列各種不同的邏輯處理
  • 如下,將一個序列函式的巢狀呼叫組合為array_reduce產生的新函式呼叫
function compose(...$functions){
    return array_reduce(
        $functions,
        function($carry,$function){
            return function($x)use($carry,$function){
                return $function($carry($x));
            };
        },
        function($x){
            return $x;
        }
    );
}
  • 效果
$compose = compose(
    // 加 2
    function ($x) {
        return $x + 2;
    },
    // 乘 4
    function ($x) {
        return $x * 4;
    }
);

$res = $compose(3); // (3+2)*4 = 20

其它

  • 類似的多值化一,javascript官方亦有提供,原理一致
  • 進一步擴充套件,如果陣列元素為實現相同介面的不同例項,則意味著初始變數(比如 request 請求)可以被多次訪問修改,而對陣列本身操作,則可以達到實現中介軟體優級的調整或固定順序處理

相關文章