18、PHP 原生魅力 - 数组 - 数组映射
对每个数组元素应用函数:array_map()
在不使用手动遍历的情况下,对数组中的每个元素执行特定的逻辑(一个函数),那么 array_map()
函数提供了一个便捷的解决方案。这个函数使得能够将一个指定的函数应用于数组的每个元素上,从而生成一个新的数组,其中包含经过修改的元素,并且保持了原数组的长度不变。
在使用 array_map()
时,第一个参数表示要应用到每个元素的函数,第二个参数是要操作的数组。然后,作为第一个参数指定的函数将针对数组中的每个元素执行,最后生成一个包含修改后的值的新数组。
让我们用一个例子来说明这个问题,计算数组中每个元素的立方:
<?php
$a = [1,2,3,4,5];
function cube(int $n): int {
return ($n * $n * $n);
}
$b = array_map('cube', $a);
print_r($b);
输出如下:
$ php 18-arraymap.php
Array
(
[0] => 1
[1] => 8
[2] => 27
[3] => 64
[4] => 125
)
在提供的例子中,变量 $a
代表输入数组,包含 5 个整数元素。函数 cube()
接受一个输入参数。在 array_map()
函数内,对输入数组(指定为第二个参数)进行迭代。对于遇到的每个元素,都会调用 cube()
函数(作为第一个参数指定,以字符串形式表示函数的名称)。
因此,array_map()
函数生成了一个新的数组 $b
,它包含 5 个元素。数组 $b
中的每个元素都是由输入数组 $a
中对应元素经过立方函数处理后得到的结果。
输入数组 $a
如下:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
输出数组 $b
如下:
Array
(
[0] => 1
[1] => 8
[2] => 27
[3] => 64
[4] => 125
)
使用多个数组
如果有多个数组变量,并且需要连接它们对应的值,你可以通过使用逗号 , 分隔每个数组,来利用 array_map()
函数处理多个数组。
下面是一个示例,展示了如何在处理多个数组时使用 array_map()
函数。这里假设 addGreeting()
函数接受多个参数(具有相同元素数量的数组):
<?php
$firstNames = ['王', '李'];
$lastNames = ['丽丽', '美美'];
function addGreeting(string $first, string $last): string {
return 'hello,' . $first . $last . '!';
}
$greetedNames = array_map('addGreeting', $firstNames, $lastNames);
print_r($greetedNames);
输出如下:
$ php 18-arraymap.php
Array
(
[0] => hello,王丽丽!
[1] => hello,李美美!
)
通过箭头函数使用多数组
这里有一个涉及多个数组进行数学计算的另一个例子。对于过去一年中的每个月(因此包含 12 个元素),有一个数组表示跑步的公里数,另一个数组表示骑自行车的公里数。目标是计算每个月总覆盖的公里数。
在这个例子中,我将不定义一个传统的函数,而是使用一个箭头函数 fn($bike, $run) => $bike + $run
,该函数返回第一个参数 $bike
和第二个参数 $run
的和。
<?php
$kmBiking = [252, 280, 294, 302, 260, 298, 302, 320, 450, 342, 312, 301];
$kmRunning = [102, 95, 101, 80, 86, 121, 114, 102, 96, 84, 95, 105];
$totalKmsPerMonth = array_map(
fn (int $bike, int $run): int => $bike + $run,
$kmBiking, $kmRunning
);
print_r($totalKmsPerMonth);
输出如下:
$ php 18-arraymap.php
Array
(
[0] => 354
[1] => 375
[2] => 395
[3] => 382
[4] => 346
[5] => 419
[6] => 416
[7] => 422
[8] => 546
[9] => 426
[10] => 407
[11] => 406
)
计算额外信息
array_map()
函数会根据为每个元素执行的指定函数返回一个元素数组作为结果。如果你需要计算额外的信息,可以结合使用 array_map()
函数和函数定义中的 use()
指令的强大功能。
例如,假设你有两个数组:一个数组记录了每个月的跑步距离,另一个数组记录了每个月的骑行距离。你可能希望计算:
- 每个月的总距离。
- 整个年度的总距离。
在这种情况下,你可以定义一个变量,比如 $totalKmsPerYear
,作为全年的总距离累加器。然后,你可以使用 use()
指令将这个变量传递给匿名函数。use()
指令特别适用于向匿名函数传递值。没有它,匿名函数可能无法访问其作用域之外定义的变量。
此外,需要注意的是,由于我们打算修改累加器变量的值,必须通过引用而非值传递给匿名函数。为了实现这一点,在变量前加上 & 符号,如 &$totalKmsPerYear
。
<?php
$kmBiking = [252, 280, 294, 302, 260, 298, 302, 320, 450, 342, 312, 301];
$kmRunning = [102, 95, 101, 80, 86, 121, 114, 102, 96, 84, 95, 105];
$totalKmsPerYear = 0;
$totalKmsPerMonth = array_map(
function (int $bike, int $run) use (&$totalKmsPerYear): int {
$totalKmsPerYear = $totalKmsPerYear + $bike + $run;
return $bike + $run;
},
$kmBiking,
$kmRunning
);
print_r($totalKmsPerMonth);
print_r($totalKmsPerYear);
输出如下:
$ php 18-arraymap.php
Array
(
[0] => 354
[1] => 375
[2] => 395
[3] => 382
[4] => 346
[5] => 419
[6] => 416
[7] => 422
[8] => 546
[9] => 426
[10] => 407
[11] => 406
)
4894