文章大纲

array_walk和array_map函数的区别详解

2019-11-28 23:26:06

虽然经常用,但不曾太留意,也不曾比较过。遂今天稍稍总结下。


当改变数组元素值,不涉及数组的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的第三个参数,也就是第二个数组的元素值了。

不过还是很值得注意:

注意:各数组长度不硬性要求一致,长度不够的,默认为空了,所以回调函数里的默认值也发挥不上用场


通过以上实践,基本就可以总结array_walk函数和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进去,不然的话无法进行运算。


我要评论
评论列表