最近在做一个小项目,由于数据来源的格式变动,要求我们代码进行调整。所以,就看了一下那块代码,是其他同事写的,思路很清晰。

其中有一处代码是这样的,出于保密考虑我已经简化并修改了变量名:

<?php
$ar = array(
  array('type' => '水果', 'name' => '苹果'),
  array('type' => '水果', 'name' => '橘子'),
  array('type' => '熟食', 'name' => '羊蹄'),
  array('type' => '水果', 'name' => '葡萄'),
  array('type' => '熟食', 'name' => '烧鸡'),
  array('type' => '熟食', 'name' => '烤鸭'),
  array('type' => '水果', 'name' => '西瓜'),
);
$info = array();
foreach($ar as $key => $value)
{
  if($value['type'])
  {
    $info[$value['type']][] = $value['name'];
  }
}
print_r($info);

这个代码很简单,就是对一个二维数组进行type排序,输出的答案是:
Array
(
[水果] => Array
(
[0] => 苹果
[1] => 橘子
[2] => 葡萄
[3] => 西瓜
)
[熟食] => Array
(
[0] => 羊蹄
[1] => 烧鸡
[2] => 烤鸭
)

)

其实对于这类数据处理,php有个方法,叫做array_reduce,官网的解释是用回调函数迭代地将数组简化为单一的值。
array_reduce($arr, callable $callback)
其中$arr 为输入数组,$callback($result , $value)接受两个参数,$result为上一次迭代产生的值,$value是当前迭代的值。

所以,刚才那个代码可以改成:

<?php
$ar = array(
  array('type' => '水果', 'name' => '苹果'),
  array('type' => '水果', 'name' => '橘子'),
  array('type' => '熟食', 'name' => '羊蹄'),
  array('type' => '水果', 'name' => '葡萄'),
  array('type' => '熟食', 'name' => '烧鸡'),
  array('type' => '熟食', 'name' => '烤鸭'),
  array('type' => '水果', 'name' => '西瓜'),
);
$info = array_reduce($ar, create_function('$v, $w', '$v[$w["type"]][]=$w["name"];return $v;'));
print_r($info);

代码即简化了,而且代码可读性也并没有变得很复杂。array_reduce在一些复杂的业务场景下,可以发挥出很多作用。

再举个例子,删除某个目录下所有a开头的文件:

<?php
array_walk(glob('E:/a*'), create_function('$v, $k', 'is_file($v)&&unlink($v);'));