18、PHP 原生魅力 - 数组 - 数组映射

作者: 温新

图书: 【原生 PHP 魅力】

阅读: 158

时间: 2024-09-08 00:04:15

对每个数组元素应用函数: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
请登录后再评论