PHP中通过回调遍历处理数组元素

作者:代码可乐    发布日期:2017年8月4日


在PHP中,使用array_map、array_walk函数,可以很方便地遍历(循环)并处理数组中的元素,它们都提供一个回调参数。下面谈一谈用法。

array_map原型

先看array_map函数,原型如下:

array array_map(callable $callback, array $array1[, array $...])

第一个参数指定回调函数,接受一个参数:元素的值。第二个及后续参数指定预处理的一个或多个数组。返回结果为处理后的数组。

array_map实例1

我们先看下如何处理一个数组的情况,直接看一下实例:

<?php
$cities = [
    'beijing' => [
        'name' => '北京',
        'population' => 20000000,
    ],
    'tianjin' => [
        'name' => '天津',
        'population' => 15000000,
    ],
    'handan' => [
        'name' => '邯郸',
        'population' => 9000000,
    ],
];

$mapCities = array_map(function($city){
    return number_format($city['population']);
}, $cities);

var_dump($mapCities);

运行结果:

array(3) {
  ["beijing"]=>
  string(10) "20,000,000"
  ["tianjin"]=>
  string(10) "15,000,000"
  ["handan"]=>
  string(9) "9,000,000"
}

此实例中,通过自定义的回调函数,取出了数组中指定元素的值做格式处理,并从回调函数中返回。array_map函数返回的数组中,包含了每个元素的处理结果。

要点:

  1. array_map函数的数组参数($cities),只能通过传值方式传递。
  2. 数组参数($cities)中的key,将保留在结果数组($mapCities)中。

array_map实例2

我们看下如何处理多个数组的情况。适用的场景是,在这些不同的数组中,同一位置的元素是相关的。我们看例子:

<?php
$cities = [
    'beijing' => [
        'name' => '北京',
        'population' => 20000000,
    ],
    'tianjin' => [
        'name' => '天津',
        'population' => 15000000,
    ],
    'handan' => [
        'name' => '邯郸',
        'population' => 9000000,
    ],
];
$cityAbbrs = ['京', '津'];

$mapedCities = array_map(function($city, $abbr){
    $city['population'] = number_format($city['population']);
    $city['abbr']       = $abbr;
    return $city;
}, $cities, $cityAbbrs);

var_dump($mapedCities);

运行结果:

array(3) {
  [0]=>
  array(3) {
    ["name"]=>
    string(6) "北京"
    ["population"]=>
    string(10) "20,000,000"
    ["abbr"]=>
    string(3) "京"
  }
  [1]=>
  array(3) {
    ["name"]=>
    string(6) "天津"
    ["population"]=>
    string(10) "15,000,000"
    ["abbr"]=>
    string(3) "津"
  }
  [2]=>
  array(3) {
    ["name"]=>
    string(6) "邯郸"
    ["population"]=>
    string(9) "9,000,000"
    ["abbr"]=>
    NULL
  }
}

要点:

  1. 回调函数接收的参数与传参数组一一对应,前者参数个数应少于或等于后者数组个数。
  2. 当其中一个数组包含元素较少时,调用时找不到此值,值为null。
  3. 参数数组中的key不再保留,结果数组中的key会被重新索引。

array_walk原型

array_walk原型如下:

bool array_walk(array &$array, callable $callback[, mixed $userdata = NULL])

第一个参数代表预处理的数组,以引用方式传递。第二个为回调函数,接受的参数最多有三个,第一个为数组元素的值,第二个为key(可不传递),第三个参数为可选,来自于array_walk函数的第三个参数。第三个参数为可选,可以指定用户自定义的变量。成功运行后,返回结果为true,反之false。对于回调参数中的元素值,我们以引用方式传递此值时,则可以直接修改其数组中的值,见下文。

array_walk实例

我们看一个实例:

<?php
$cities = [
    'beijing' => [
        'name' => '北京',
        'population' => 20000000,
    ],
    'tianjin' => [
        'name' => '天津',
        'population' => 15000000,
    ],
    'handan' => [
        'name' => '邯郸',
        'population' => 9000000,
    ],
];

array_walk($cities, function(&$city, $slug) {
    if ($slug == 'handan') {
        return;
    }
    $city['population'] = number_format($city['population']);
});
var_dump($cities);

$unit = '人';
array_walk($cities, function(&$city, $slug, $unit) {
    $city['population'] .= $unit;
}, $unit);
var_dump($cities);

运行结果:

array(3) {
  ["beijing"]=>
  array(2) {
    ["name"]=>
    string(6) "北京"
    ["population"]=>
    string(10) "20,000,000"
  }
  ["tianjin"]=>
  array(2) {
    ["name"]=>
    string(6) "天津"
    ["population"]=>
    string(10) "15,000,000"
  }
  ["handan"]=>
  array(2) {
    ["name"]=>
    string(6) "邯郸"
    ["population"]=>
    int(9000000)
  }
}
array(3) {
  ["beijing"]=>
  array(2) {
    ["name"]=>
    string(6) "北京"
    ["population"]=>
    string(13) "20,000,000人"
  }
  ["tianjin"]=>
  array(2) {
    ["name"]=>
    string(6) "天津"
    ["population"]=>
    string(13) "15,000,000人"
  }
  ["handan"]=>
  array(2) {
    ["name"]=>
    string(6) "邯郸"
    ["population"]=>
    string(10) "9000000人"
  }
}

我们先看第一个array_walk的调用情况。
通过引用方式传递了参数(&$city),通过赋值直接修改了其值,通过输出结果可以看到原数据内容已变化。

再看第二次调用。
在array_walk函数和回调函数的参数里,指明了第三个参数($unit),用来传递用户自定义的变量。

要点:

  1. 在回调函数中,以引用方式传参可直接修改数组元素的值。

array_map和array_walk对比

  1. 处理数组元素的值时,array_map以传值方式实现,array_walk则可以传址;即array_map将处理后的数组以结果返回,array_walk则是直接修改。
  2. 只处理一个数组时,array_map不获取也无法获取元素的key,array_walk则可以获取。

总之,适合使用array_map的场景,用其更安全。array_walk则更强大。

(完)


版权声明:知识共享署名-非商业性使用-禁止演绎 4.0 国际

发表评论

电子邮件地址不会被公开。 必填项已用*标注