老规矩,先上代码再说话。
";
}
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);
?>
如果不希望回调函数会改变数组的值的话,f1改为不返回值,f2改为不传递引用即可做到。