虽然经常用,但不曾太留意,也不曾比较过。遂今天稍稍总结下。
当改变数组元素值,不涉及数组的key时,array_walk和array_map均可。
例如要给下面的数组的每个元素, 都加个“很帅”。
用array_walk可以如下写:
$arr = array( "gaoyixiang"=>"高以翔", "gutianle" =>"古天乐", "zhaicoder" =>"翟码农" ); array_walk($arr, function($value, $key, $suffix){ echo $value.$suffix."<br>"; }, "很帅");
array_walk的第3个参数,作为回调函数的第三个参数,正如上面的“很帅”传给了$suffix这个参数。
上面代码只是输出字符串到浏览器,结果如下:
高以翔很帅 古天乐很帅 翟码农很帅
并没有改动$arr这个数组的内容。如果要给数组的每个元素的值, 都加个“很帅”,就$value传引用,然后修改$value的值,具体代码如下:
array_walk($arr, function(&$value, $key, $suffix){ $value = $value.$suffix; }, "很帅");
此时再var_dump($arr)看结果,就会发现数组的每个值已经发生变化了。
array_map也可以实现同样的目的:
function append($ele){ return $ele =$ele."很帅"; } $afterArr = array_map('append', $arr); var_dump($arr); var_dump($afterArr);
查看结果,原数组$arr内容并不会发生改变,数组改变后的效果赋值给$afterArr数组了。
试了一下像如下这样写,也是可以的,只是意义没啥变化。
function append($ele, $t="很帅"){ return $ele =$ele.$t; } $afterArr = array_map('append', $arr);
开发最好遵守开闭原则,就是不要轻易去改类内部或函数内部的代码,将容易发生变化的变量放在函数外或类外部控制。代码稍稍优化后如下:
$t = "很帅"; $afterArr = array_map(function($ele) use($t){ return $ele =$ele.$t; }, $arr);
由于array_map的回调函数的参数不含有数组的Key值部分,所以当数组的改变需要用到key值时,array_map就无能为力了。
例如将下面数组中的key值(颜色)跟value值连接起来,就只能用array_walk了。
$arr = ["white" => "rabbit", "yellow"=>"moon", "red"=>"rose"]; array_walk($arr, function(&$value, $key, $prefix){ $value = $prefix.$key." ".$value; }, "I love "); var_dump($arr);
打印结果如下:
array(3) { ["white"]=> string(19) "I love white rabbit" ["yellow"]=> string(18) "I love yellow moon" ["red"]=> string(15) "I love red rose" }
本文是翟码农个人博客蓝翟红尘里php分类下的有关函数使用总结的文章,转载请注明出处:http://www.zhai14.com/blog/the-difference-between-array_walk-and-array_map.html
这里顺便提下array_walk_recursive方法,效果跟array_walk一样,只是它可以满足与多层嵌套的数组。类如:
$arr = array( "xiaohudui" =>["suyoupeng" => "苏有朋", "quqilong"=>"吴奇隆"], "gutianle" =>"古天乐", "zhaicoder" =>"翟码农" ); array_walk_recursive($arr, function($value, $key, $suffix){ echo $value.$suffix."<br>"; }, "很帅");
array_walk只能针对一维数组,对上面的数据情况它就无法处理了。
看array_map还支持多数组,具体是怎么个用法,看下面例子:
function append($ele, $t="很帅"){ return $ele =$ele.$t; } $numArr = [1,2,3,4,5]; $arr = ["white" => "rabbit", "yellow"=>"moon", "red"=>"rose"]; $afterArr = array_map('append', $numArr, $arr); var_dump($afterArr);
打印结果:
array(5) { [0]=> string(7) "1rabbit" [1]=> string(5) "2moon" [2]=> string(5) "3rose" [3]=> string(1) "4" [4]=> string(1) "5" }
结果里不再有“很帅”这个词,可见此时回调函数的第二个参数已经传的是array_map的第三个参数,也就是第二个数组的元素值了。
不过还是很值得注意:
注意:各数组长度不硬性要求一致,长度不够的,默认为空了,所以回调函数里的默认值也发挥不上用场
1. array_walk的参数,数组在第一位。array_map的在后面,由array_map支持多数组,就可知道为何array_map的数组参数放在后面了。
记忆诀窍:走,去数钱(walk,数组,钱通‘前’),即array_walk函数的数组在前面。
2. array_walk回调参数有key值,而array_value没有。
3. array_walk可通过索引来改变原数组内容,array_map不能改变原数组内容,只能用新数组来接收改变后的数组。
4. 由array_map的运算结果需要新数组变量来接收可顺便总结出此点:array_map的回调函数必须要return运算后的值。
5. array_map的回调函数还可以是php的自带函数,而array_walk只支持自定义函数。(此点文中未概括,大家自行实践了)
当回调函数里数据运算需要很多外部变量时,就直接用foreach好了,不然还得一个个在回调函数里把一个个外部变量use进去,不然的话无法进行运算。