PHP 数组函数实战:array_map 与 filter 用法

19 ℃ 0 条
内容摘要用 array_map 把回调换成箭头函数后输出变成一片 0,链式写法又报参数类型错误。根源在回调参数顺序、返回值处理与键名规则。本文用一段订单数据拆解 array_map 等函数的边界差异,并给出先过滤再映射的写法与常见报错的排查思路。
PHP 数组函数实战:array_map 与 filter 用法

PHP 数组函数实战

用 array_map 把回调换成箭头函数后,输出却变成一片 0;链式写法 array_filter(array_map()) 又报「参数类型错误」。这两个报错都指向同一件事:PHP 数组函数对参数类型、回调参数顺序、键名保留各有固定规则。本文用一段订单数据把 array_map、array_filter、array_walk 的边界讲清楚。

一、array_map 的返回与回调参数顺序

1. 回调返回值组成新数组

array_map 不会改动原数组,它把每个元素交给回调,再用回调的返回值拼出一个等长的新数组。回调返回什么,新数组里就是什么;回调里只写 echo 而没有 return,新数组里对应位置就是 null。

$nums = [1, 2, 3];
$double = array_map(fn ($n) => $n * 2, $nums); // [2, 4, 6]

2. 多数组时回调按位接收

传多个数组时,PHP 会把它们的同名键按下标对齐,再依次传给回调。回调的参数顺序与数组传入顺序一致,先传的数组对应第一个参数。元素个数不齐时,短数组缺失的位置补 null,多余的元素被丢弃。

二、闭包 use 与键名保留

1. 匿名函数必须显式 use

array_walk 的回调默认按值接收元素、按值接收键,想改元素必须把参数声明为引用。回调要用到外部变量,必须在 use 里显式列出并加 & 引用,否则函数体内取不到、只会得到 null。

$rate = 0.9;
array_walk($order, function (&$item) use ($rate) {
    $item = $item * $rate;
});

2. 键名在单数组时被保留

这是最容易被忽略的差异:单个数组时 array_map 保留原键名,过滤或运算后键名不会重排;换成多数组传入,结果键名会被重排为从 0 开始的连续整数。array_filter 同样保留原键名,删掉元素后键名会出现空缺,直接 json_encode 会得到对象而非数组,需要先用 array_values 重排。

三、链式写法与常见误用

1. 先过滤再映射更省开销

链式写法按从左到右的顺序执行,于是 array_map(array_filter()) 会先映射全部元素再过滤,回调被多执行一遍。把 array_filter 放在内层,回调只处理保留下来的元素:

$total = array_sum(array_map(
    fn ($o) => $o['qty'] * $o['price'],
    array_filter($order, fn ($o) => $o['status'] === 'paid')
));

2. 回调签名不匹配的三种报错

链式调用报参数类型错误,多半是前一环的返回值不是数组:array_filter 未命中任何元素时返回空数组,而 usort 要求参数必须是引用,不能直接套在 array_map 外面。回调接收到的值类型也常与预期不符,先打印第一项再决定排序或转换逻辑。

$first = reset($order);
print_r($first); // 确认键值与类型后再写回调

关键配置提示

  • 回调只用箭头函数时不需要 use,但箭头函数无法修改外部变量。
  • 需要改动元素本身用 array_walk,需要新元素用 array_map。
  • 过滤后若结果要当数组用,先套一层 array_values。

上一篇:钉钉审批增加附件

下一篇:没有了

发表评论 (已有0条评论)

快来评论,快来抢沙发吧~