ThinkPHP Collection 的 map 逐项转换不删不跳、保留空值,reduce 必须显式返回累加器且初始值决定返回类型;二者常组合用于数据规整与聚合统计。

ThinkPHP 的 Collection(集合)类提供了 map 和 reduce 两个核心数据处理方法,它们不是语法糖,而是函数式编程思想在 PHP 中的落地——关键不在“会不会写”,而在“是否理解闭包行为与返回值契约”。
map:逐项转换,不删不跳,空值也占位
map 接收一个闭包,对每个元素执行变换,返回新 Collection,原集合不变。它不做过滤,也不重排键名。
- 若闭包返回
null或0或空字符串,对应位置仍保留该值,不会被跳过 - 想同时转换+筛选?必须链式接
filter(),再用values()重置索引 - 键名默认继承原集合(如关联数组的字符串键),需
values()才得连续数字索引
示例:
$data = collect(['a' => 1, 'b' => 2, 'c' => null]); $result = $data->map(fn($v) => $v * 10); // 返回 collect(['a' => 10, 'b' => 20, 'c' => null]),不是 [10, 20]
reduce:必须显式返回累加器,初始值决定类型
reduce 对集合做累积运算,只返回一个最终值。它的回调接收两个参数:$carry(累加器)和 $item(当前项),每次必须 return $carry,否则下一轮 $carry 变为 null,逻辑中断。
立即学习“PHP免费学习笔记(深入)”;
- 不传初始值时,第一项自动作为 $carry —— 若集合为空,直接报错
- 初始值类型决定最终返回类型:传
0得整数,传[]得数组,传collect()得 Collection - 避免在 reduce 里修改外部变量或调用 DB 查询等副作用操作
示例:
$scores = collect([85, 92, 78, 96]); $total = $scores->reduce(fn($carry, $item) => $carry + $item, 0); // 351 $avg = $total / $scores->count(); // 需额外计算平均值
map + reduce 组合:常见聚合场景的简洁写法
单独用 reduce 做统计略显笨重,常配合 map 提前规整数据结构。
- 求用户年龄总和:先
map(fn($u) => $u['age'] ?? 0)提取数值,再reduce(..., 0) - 拼接所有标题并用逗号分隔:先
map(fn($post) => $post['title']),再reduce(fn($carry, $item) => $carry ? "$carry,$item" : $item, '') - 按状态分组计数:用
map转成['active' => 1, 'inactive' => 1, ...],再reduce累加同 key



















