广告

PHP数组合并:遇到相同键如何在合并时保留第一个值?完整实现与代码示例

概念与需求

重复键的行为

在 PHP 的数组合并场景中,常见的做法往往依赖内置函数,例如 array_merge,其会对具有相同键的值进行覆盖。这一行为在处理配置、参数合并等场景时可能带来意外结果,因此需要一种方法来实现遇到相同键时保留第一个值的合并策略。

本文聚焦在如何在合并时保留第一个值的需求,介绍两种思路:使用原生运算符实现简单方案,以及通过自定义函数实现更细粒度的控制(包括递归合并)。

常用方案与示例

使用数组并集运算符 + 实现保留第一个值

最直接的做法是使用数组并集运算符,该运算符在遇到重复键时会保留左侧数组中的值,右侧的值会被忽略。对于简单的一级键值对,这是一个快速且无需额外代码的解决方案

下面是一个示例,演示如何在合并时保留第一组键值的做法:

 'Alice', 'age' => 30, 'city' => 'New York'];
$b = ['age' => 31, 'city' => 'Beijing', 'country' => 'USA'];// 左侧优先:b 中相同键不会覆盖 a 的值
$merged = $a + $b;print_r($merged);
?>

输出结果中,name 始终来自第一个数组的值,而键 age、city 遇到重复时也以左侧为准,新增键 country 会正确合并进来;这对于简单配置合并来说是一个高效的选择。

PHP数组合并:遇到相同键如何在合并时保留第一个值?完整实现与代码示例

完整实现:自定义递归合并

递归思路

对于嵌套结构,简单的右向覆盖并不总能满足需求,因此需要一个递归合并的实现:遇到相同键时,如果两侧的值都是数组,则对其进行递归合并;否则保留左侧的值,不覆盖。

通过自定义函数,可以在保留第一值的同时,对嵌套数组结构进行深度合并,从而处理复杂的配置对象或多层键值对。

完整实现代码

下面给出一个明确可用的实现:

 $value) {if (!array_key_exists($key, $result)) {// 第一次遇到该键,直接写入$result[$key] = $value;} else {// 针对嵌套数组做递归合并if (is_array($result[$key]) && is_array($value)) {$result[$key] = array_merge_preserve_first($result[$key], $value);}// 其他情况保持左侧的值,不覆盖}}}return $result;
}// 例子
$a = ['name' => 'Alice','age'  => 30,'preferences' => ['likes' => ['php', 'js'],'dislikes' => ['coffee']]
];
$b = ['age' => 31,'city' => 'Beijing','preferences' => ['likes' => ['laravel'],'dislikes' => ['tea'],'music' => ['rock']]
];$merged = array_merge_preserve_first($a, $b);
print_r($merged);
?>

在这个实现中,顶层键值对优先保留来自最左侧参数的值,若键对应的值是数组,则会进行递归合并,进一步保留第一层中的更深层结构的值。实际运行后,输出会显示 name、age、city 与 nested 的偏好配置被合理合并,而重复键中的值保持来自左侧输入。

对比与性能考量

适用场景与性能差异

简单场景优先考虑使用 + 运算符,它实现简单、性能极佳,且语义清晰:左侧优先,右侧补充。当数组结构比较扁平、且无需处理嵌套合并时,这是最省事的方案。

如果遇到<嵌套结构或多层键值对,且需要保持第一值在各层级都生效,那么自定义递归合并的方案更具鲁棒性。然而,递归合并在大数据量或深层嵌套时可能带来性能损耗,需要谨慎权衡。

广告

后端开发标签