array_reduce 的理解

看 laravel 時遇到一個函數,琢磨了半天也沒有理解,最後還是查了下資料才完全理解。

這裏還是再做下筆記加深下印象。

php官方是這麼寫的:

 array_reduce(array $array, callable $callback, [mixed $initial = null ])

什麼意思呢,先舉個簡單點兒的栗子:


<?php

function sum($carry, $item) {
    var_dump($carry, $item);
    $carry += $item;
    echo '<br><hr>';
    return $carry;
}

$a = array(1, 2, 3, 4, 5);

var_dump(array_reduce($a, 'sum', 10)); 

輸出結果爲:

int(10) int(1)
int(11) int(2)
int(13) int(3)
int(16) int(4)
int(20) int(5)
int(25)

可以看出 array_reduce 的第三個參數傳給 callable sum 並作爲第一個參數,然後 array $a 的第一個元素作爲第二個參數,即sum(10, 1),然後把計算結果返回給下一次迭代即 sum(11, 2),依次類推直至程序結束。

簡單的理解了,再來點複雜的,不過在開始之前,先來熟悉下匿名函數:

匿名函數:

$name = 'well';
$greet = function () use ($name){
    echo 'hello ' ,$name;
};
$greet ();

# hello well

function closureFunc($name){
    $func = function() use ($name){
        echo "hello" ,$name;
    };
    $func();
}
closureFunc('well');
# hello well

接下來就是重點了,在 array_reduce 中使用匿名函數,舉個例子,西瓜姑娘接到閨蜜電話出去玩,肯定要先化妝打扮一下再出門:

class MakeUp {
    public static function handle(Closure $next) {
        echo '化妝打扮', '<br>';;
        $next();

    }
}

$firstSlice = function (){
    echo '我要出去玩了~', '<br>';
};

$arr = [
    'MakeUp'
];

function getSlice(){
    return function ($stack, $pipe){
        return function () use ($stack, $pipe){
            return $pipe::handle($stack);
        };
    };
}

$go = array_reduce($arr, getSlice(), $firstSlice);

$go();

輸出結果爲:

化妝打扮
我要出去玩了~

這段程序執行時首先運行 getSlice($firstSlice, 'DressUp'),然後拼裝執行 MakeUp::handle()
MakeUp::handle() 中先去化妝打扮,然後再通過匿名Closure $next執行 $firstSlice 出門去玩。

如果覺得僅僅是化妝還不夠,還要再穿條美美的裙子出門,那麼再對上邊的處理進行改造,添加穿裙子的過程:


class Skirt {
    public static function handle(Closure $next) {
        echo '穿上裙子', '<br>';
        $next();
    }
}

$arr = [
    'MakeUp',
    'Skirt'
];

那麼執行過程會變成什麼樣呢?爲了看清楚執行過程,先在 getSlice 中加上打印:


function getSlice(){
    return function ($stack, $pipe){
        echo '<pre>';
        echo 'stack :';
        var_dump($stack);
        echo '<hr>';
        echo 'pipe :';
        var_dump($pipe);
        echo '</pre>';
        echo '<br><hr>';

        return function () use ($stack, $pipe){
            return $pipe::handle($stack);
        };
    };
}

可以看到第一次執行時,stack 是一個匿名函數 , 也對應了官網介紹的作爲第一次迭代時,$carryinitial,也就是$firstSlicepipeMakeUp,但是它並沒有執行而是直接返回了,也就是直接返回

 
function ($stack, $pipe){
        return function () use ($stack, $pipe){
            return $pipe::handle($stack);
        };

匿名函數 function ($stack, $pipe)被返回後,也就相當於一個 array_reduce($arr, getSlice(), $firstSlice);,不同的是匿名函數 function ($stack, $pipe)代替了$firstSlice被傳給下一次迭代。

第二次迭代時執行 Skire::handle,先穿上了美美的裙子,然後$next 執行匿名函數 function ($stack, $pipe),也就是去MakeUp::handle,化妝後繼續執行 $next,也就是匿名函數 $firstSlice

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章