在 PHP 项目里,经常会拿到两个由 stdClass 对象组成的数组,它们都包含 code 字段作为唯一标识。如果想把这两个数组合并,同时去掉 code 重复的项,可以用临时的关联数组来实现。

问题说明
假设有两个数组 $listA 和 $listB,每个元素都是 stdClass,拥有 code 和 name 属性。直接合并可能会出现相同 code 的对象,需要进一步过滤。
实现思路
我们以 code 的值为键,把对象放进一个新数组。如果后面遇到相同的 code,就覆盖或者跳过,取决于想保留哪一份数据。最后用 array_values 让结果变回连续下标的数组。
基础示例代码
下面演示保留后面数组对象的方式:
<?php
$listA = [
(object)['code' => 'a', 'name' => '苹果'],
(object)['code' => 'b', 'name' => '香蕉']
];
$listB = [
(object)['code' => 'b', 'name' => '香蕉更新'],
(object)['code' => 'c', 'name' => '橙子']
];
$merged = [];
// 先放 A
foreach ($listA as $item) {
$merged[$item->code] = $item;
}
// 再放 B,重复 code 时 B 覆盖 A
foreach ($listB as $item) {
$merged[$item->code] = $item;
}
// 重置下标,得到 stdClass 对象数组
$result = array_values($merged);
print_r($result);
?>
保留前面数组的对象
如果希望重复时保留 $listA 中的数据,只需在放 B 时判断是否存在:
<?php
$merged = [];
foreach ($listA as $item) {
$merged[$item->code] = $item;
}
foreach ($listB as $item) {
// 仅当 code 不存在时才放入
if (!isset($merged[$item->code])) {
$merged[$item->code] = $item;
}
}
$result = array_values($merged);
?>
封装成函数
可以把逻辑封装起来方便复用:
<?php
function merge_by_code(array $a, array $b, bool $keepFirst = false): array {
$tmp = [];
foreach ($a as $obj) {
$tmp[$obj->code] = $obj;
}
foreach ($b as $obj) {
if ($keepFirst && isset($tmp[$obj->code])) {
continue;
}
$tmp[$obj->code] = $obj;
}
return array_values($tmp);
}
?>
小结
利用 code 作为临时键名是最直接有效的去重合并方式。它在处理接口数据、配置文件对象时都很实用,代码也容易理解和维护。