在PHP开发中,处理数组时经常会遇到需要合并多个数组,同时针对重复项累加其计数字段(比如REPEAT字段)的场景,比如统计用户多次提交的数量、合并分页查询的聚合数据等。下面我们来看具体的实现方法。

基础循环遍历实现方案
最直观的思路是先遍历所有待合并的数组,用临时数组存储已经出现过的项,遇到重复项就把REPEAT字段的值累加进去。假设我们有如下两个待合并的数组:
<?php
// 第一个数组,包含id和REPEAT计数字段
$arr1 = [
['id' => 1, 'name' => '商品A', 'REPEAT' => 2],
['id' => 2, 'name' => '商品B', 'REPEAT' => 3],
];
// 第二个数组,存在和第一个数组重复的项
$arr2 = [
['id' => 1, 'name' => '商品A', 'REPEAT' => 1],
['id' => 3, 'name' => '商品C', 'REPEAT' => 5],
];
// 合并后的结果数组
$result = [];
// 遍历第一个数组,初始化结果数组
foreach ($arr1 as $item) {
$result[$item['id']] = $item;
}
// 遍历第二个数组,处理重复项
foreach ($arr2 as $item) {
$id = $item['id'];
if (isset($result[$id])) {
// 如果存在重复项,累加REPEAT字段
$result[$id]['REPEAT'] += $item['REPEAT'];
} else {
// 不存在则直接加入结果数组
$result[$id] = $item;
}
}
// 重置数组索引,去掉id作为键的结构
$result = array_values($result);
print_r($result);
?>
上面的代码执行后,输出的结果中id为1的商品的REPEAT字段会变成3,也就是2加1的结果,符合我们的需求。这种方法的逻辑清晰,适合处理结构简单的数组。
使用内置函数优化实现
如果待合并的数组数量比较多,或者数组结构更复杂,我们可以用array_reduce函数简化代码逻辑,减少重复的循环代码。下面是优化后的实现:
<?php
$arr1 = [
['id' => 1, 'name' => '商品A', 'REPEAT' => 2],
['id' => 2, 'name' => '商品B', 'REPEAT' => 3],
];
$arr2 = [
['id' => 1, 'name' => '商品A', 'REPEAT' => 1],
['id' => 3, 'name' => '商品C', 'REPEAT' => 5],
];
$arr3 = [
['id' => 2, 'name' => '商品B', 'REPEAT' => 2],
['id' => 4, 'name' => '商品D', 'REPEAT' => 4],
];
// 把所有待合并的数组放到一个数组中
$allArrays = [$arr1, $arr2, $arr3];
$result = array_reduce($allArrays, function ($carry, $currentArray) {
foreach ($currentArray as $item) {
$id = $item['id'];
if (isset($carry[$id])) {
$carry[$id]['REPEAT'] += $item['REPEAT'];
} else {
$carry[$id] = $item;
}
}
return $carry;
}, []);
$result = array_values($result);
print_r($result);
?>
这种方式可以一次性处理多个数组,不需要为每个数组单独写遍历逻辑,代码的可维护性更好。如果数组的重复判断依据不是id,而是其他字段,只需要修改$id = $item['id']这一行对应的字段名即可。
处理多维复杂数组的场景
如果数组的重复判断需要基于多个字段,比如同时匹配id和type两个字段才算重复项,我们可以把多个字段拼接成临时键来处理。示例如下:
<?php
$arr1 = [
['id' => 1, 'type' => 'A', 'REPEAT' => 2],
['id' => 1, 'type' => 'B', 'REPEAT' => 3],
];
$arr2 = [
['id' => 1, 'type' => 'A', 'REPEAT' => 1],
['id' => 1, 'type' => 'C', 'REPEAT' => 5],
];
$result = [];
$allArrays = [$arr1, $arr2];
foreach ($allArrays as $array) {
foreach ($array as $item) {
// 拼接id和type作为临时键
$key = $item['id'] . '_' . $item['type'];
if (isset($result[$key])) {
$result[$key]['REPEAT'] += $item['REPEAT'];
} else {
$result[$key] = $item;
}
}
}
$result = array_values($result);
print_r($result);
?>
执行后可以看到,id为1、type为A的项REPEAT字段累加为3,而id为1、type为B和C的项分别保留各自的数值,符合多字段判断重复的需求。
注意事项
- 如果REPEAT字段可能不存在,需要先判断字段是否存在,避免报错,比如可以用
isset($item['REPEAT']) ? $item['REPEAT'] : 0来设置默认值。 - 如果数组元素数量非常多,建议先评估循环的性能,必要时可以考虑用哈希表结构优化临时存储的逻辑。
- 合并完成后如果需要保持原数组的键名顺序,可以调整
array_values的调用时机,或者不用重置索引。