php中的array_map,array_walk以及匿名函数

老规矩,先上代码再说话。

";
}


function showObj($obj)
{
  echo $obj . " ";
}


//mswap传入的是引用类型。
function mswap(&$a,&$b)
{
  $tmp=$a;
  $a=$b;
  $b=$tmp;
}


function bubbleSort(&$cols)
{
  $len=count($cols);
  for ($i=0; $i <$len ; $i++)
  {
    for ($j=1; $j < $len-$i; $j++)
    {
      if ($cols[$j-1]>$cols[$j])
      {
        mswap($cols[$j-1],$cols[$j]);
      }
    }
  }
}


$data = array(8,2,3,9,0,45,35,235);
//排序
bubbleSort($data);
//打印数组
showArray($data);
//使用回调函数依次遍历打印数组
array_map('showObj',$data);
echo "
"; //使用匿名函数遍历打印数组 array_map(create_function('$obj','echo $obj." " ;'),$data); echo "
"; //使用新的方法(php5.3+)创建匿名函数 array_map(function($obj){echo $obj. " ";},$data); //匿名函数捕获外部变量 $msg="val:"; array_map(function($obj)use ($msg){echo $msg.$obj." ";},$data);  ?>


程序的输出:


代码的功能十分简单,先初始化一个数组,然后对其排序,最后使用三种不同的方式将其打印输出。

排序的算法使用最简单的冒泡排序,不做赘述。

需要注意的有:

(1)排序函数和交换函数都使用了传递引用的方法。若使用传值方式的话,排序和交换函数不会生效,因为此时函数实际上操作的是参数对象的拷贝。

(2)array_map是php自带的,其作用是为数组中的每个对象依次调用传入的函数。此种方式称为回调。

(3)create_function可以创建一个匿名函数。在最后一个打印示例中,正是将其创建的匿名函数作为array_map的参数使用。


实际上有经验的程序员都知道,不管是C++11还是php中,匿名函数的效率偏低的。那么为什么还要使用匿名函数呢?为什么C#和java的新标准也纷纷支持它呢?

因为有名函数虽然看起来直观,但是存在着管理的代价。多一个函数,就多一个需要管理的地方。而且对于一个“微型”的代码片段而言,单独为其编写一个有名函数亦显得代码不够紧凑。然而这也绝不意味着匿名函数可以被滥用,在代码片段过大时,使用匿名函数会严重破坏可读性。对匿名函数的使用要视情况而定。

create_function有一个问题,就是它创建的匿名函数要执行的代码被放在一个字符串中,易读性不是很好。

所幸在php5.3+中有一个新函数用来创建匿名函数。来看看如何使用(依然通过匿名函数来遍历数组)。

//使用新的方法(php5.3+)创建匿名函数
array_map(function($obj){echo $obj. " ";},$data);

是不是优雅多了? →_→...

还有一个问题:现在匿名函数只能使用它自己的参数,如果它需要使用自己作用域外部的变量怎么办呢?php中的use关键字对此提供了支持:

//匿名函数捕获外部变量
$msg="val:";
array_map(function($obj)use ($msg){echo $msg.$obj." ";},$data);

此时输出为:  

val:0 val:2 val:3 val:8 val:9 val:35 val:45 val:235


另外本例中的array_map对数组只是实行了遍历,回调函数未改变数组中的元素。若回调函数要改变数组的内容,则需要通过返回值来接收。

php中另有一个array_walk函数,功能与array_map一样,但是在回调函数需要改变数组中的数据的时候,它是通过传递数组的引用来完成。

来看看示例:

";
var_dump($data);
?>

代码也很简单,使用array_map依次调用回调f1将数组中的每个值乘以100,然后再使用array_walk依次调用回调f2将数组中的每个值除以100。

如果不希望回调函数会改变数组的值的话,f1改为不返回值,f2改为不传递引用即可做到。






你可能感兴趣的:(php)