array_reduce 函数
array_reduce — 用回调函数迭代地将数组简化为单一的值
array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] )
array
输入的 array。
callback
callback ( mixed $carry , mixed $item ) : mixed
carry
携带上次迭代里的值; 如果本次迭代是第一次,那么这个值是 initial。
item
携带了本次迭代的值。
initial
如果指定了可选参数 initial,该参数将在处理开始前使用,或者当处理结束,数组为空时的最后一个结果。
示例1:不带初始值
$arr = ['AAAA', 'BBBB', 'CCCC'];
$res = array_reduce($arr, function($carry, $item){
return $carry . $item;
});
返回值:AAAABBBBCCCC
示例2:带初始值
$arr = ['AAAA', 'BBBB', 'CCCC'];
$res = array_reduce($arr, function($carry, $item){
return $carry . $item;
}, 'INIT_');
返回值:INIT_AAAABBBBCCCC
示例3:如果前一个返回的不是字符串,而是闭包呢?
$arr = ['AAAA', 'BBBB', 'CCCC'];
$res = array_reduce($arr, function($carry, $item){
return function() use ($item){
return $item;
};
});
var_dump($res);
object(Closure)#2 (1) {
["static"]=>
array(1) {
["item"]=>
string(4) "CCCC"
}
}
var_dump($res());
string(4) "CCCC"
$res为闭包,闭包打印的结果是传入的参数数组,所以示例中最终返回的是CCC对应的闭包。
示例4:将前面的闭包都保存下来
$arr = ['AAAA', 'BBBB', 'CCCC'];
$res = array_reduce($arr, function($carry, $item){
return function() use ($carry, $item){
return $item;
};
});
var_dump($res);
var_dump($res());
打印
object(Closure)#4 (1) {
["static"]=>
array(2) {
["carry"]=>
object(Closure)#3 (1) {
["static"]=>
array(2) {
["carry"]=>
object(Closure)#2 (1) {
["static"]=>
array(2) {
["carry"]=>
NULL
["item"]=>
string(4) "AAAA"
}
}
["item"]=>
string(4) "BBBB"
}
}
["item"]=>
string(4) "CCCC"
}
}
string(4) "CCCC"
可见返回的是一个嵌套了三层闭包的闭包,使用use闭包来将一个闭包包含在另一个闭包里面。这里我们只是打印了最外层的值,并没有递归来解包。
示例5:将前面的闭包都保存下来,并递归解包
$arr = ['AAAA', 'BBBB', 'CCCC'];
$res = array_reduce($arr, function($carry, $item){
return function() use ($carry, $item){
var_dump($item);
if(is_null($carry)){
var_dump('carry is null');
return strtolower($item);
}elseif($carry instanceof \Closure){
var_dump($carry());
return strtolower($item);
}
};
});
var_dump($res);
var_dump($res());
打印
object(Closure)#4 (1) {
["static"]=>
array(2) {
["carry"]=>
object(Closure)#3 (1) {
["static"]=>
array(2) {
["carry"]=>
object(Closure)#2 (1) {
["static"]=>
array(2) {
["carry"]=>
NULL
["item"]=>
string(4) "AAAA"
}
}
["item"]=>
string(4) "BBBB"
}
}
["item"]=>
string(4) "CCCC"
}
}
string(4) "CCCC"
string(4) "BBBB"
string(4) "AAAA"
string(13) "carry is null"
string(4) "aaaa"
string(4) "bbbb"
string(4) "cccc"
嵌套闭包的解包方式和递归的方式类似,它是先从外到内,然后从内回归到外面,所以输出结果是这样的。