array_reduce与闭包嵌套

50 篇文章 2 订阅
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"

嵌套闭包的解包方式和递归的方式类似,它是先从外到内,然后从内回归到外面,所以输出结果是这样的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值