PHP实现保留数组键的递归数组合并函数的问题咨询
数组递归合并函数优化建议
需求说明
实现my_merge_func函数,合并两个数组并保留键名,规则如下:
- 若$array_1中存在对应键,保留其值;
- 若$array_1中不存在对应键,添加$array_2的键值对;
- 子数组递归执行上述规则。
测试场景与预期结果
测试用例1
$array_1 = array( 'some_one' => 'some_text', 'array_1' => array( 'value_1_1', 'value_1_2' ), ); $array_2 = array( 'some_one' => 'some_text_2', 'array_0' => array( 'value_0_1', 'value_0_2' ), 'array_1' => array( 'value_defaults_1_1', 'value_defaults_1_2' ), 'array_2' => array( 'value_defaults_2_1', 'value_defaults_2_2' ), ); // 预期合并结果 $array_true = array( 'some_one' => 'some_text', 'array_0' => array( 'value_0_1', 'value_0_2' ), 'array_1' => array( 'value_1_1', 'value_1_2' ), 'array_2' => array( 'value_defaults_2_1', 'value_defaults_2_2' ), );
测试用例2(最初设计场景)
$array_1 = array( 'array_key' => array( 'array_key_1' => 1, 'array_key_2' => 2, 'array_key_3' => 3, ), ); $array_2 = array( 'array_key' => array( 'array_key_1' => null, 'array_key_2' => null, 'array_key_3' => null, 'array_key_4' => null, 'array_key_5' => null, ), ); // 预期合并结果 $array_true = array( 'array_key' => array( 'array_key_1' => 1, 'array_key_2' => 2, 'array_key_3' => 3, 'array_key_4' => null, 'array_key_5' => null ), );
现有函数代码
function my_merge_func($array_1, $array_2) { $merged = $array_1; foreach ($array_2 as $key => $value) { if ( empty($array_1[ $key ]) ) { $merged[ $key ] = $value; } else if(is_array($value) && is_array($array_1[ $key ])) { $merged[ $key ] = my_merge_func($array_1[ $key ], $value); } } return $merged; } // 调试代码 var_dump(my_merge_func($array_1,$array_2)); var_dump($array_true); var_dump(my_merge_func($array_1,$array_2) === $array_true);
当前函数输出(测试用例1)
array(4) { ["some_one"]=> string(9) "some_text" ["array_1"]=> array(2) { [0]=> string(9) "value_1_1" [1]=> string(9) "value_1_2" } ["array_0"]=> array(2) { [0]=> string(9) "value_0_1" [1]=> string(9) "value_0_2" } ["array_2"]=> array(2) { [0]=> string(18) "value_defaults_2_1" [1]=> string(18) "value_defaults_2_2" } }
问题分析与优化方案
核心问题
原函数使用empty($array_1[$key])判断是否需要替换值,empty()会将0、''、null、false等有效值判定为空,导致当$array_1的键对应值为这些类型时,会错误被$array_2的值覆盖,不符合“存在键则保留原值”的规则。比如在测试用例2中,若$array_1的某个键值为0,原函数会错误替换为$array_2的null。
优化后的函数
将判断逻辑从empty()改为array_key_exists(),准确检查键是否存在,而非值是否为空:
function my_merge_func($array_1, $array_2) { $merged = $array_1; foreach ($array_2 as $key => $value) { // 检查键是否不存在于$array_1 if (!array_key_exists($key, $array_1)) { $merged[$key] = $value; } // 若键存在且均为数组,则递归合并 else if (is_array($value) && is_array($array_1[$key])) { $merged[$key] = my_merge_func($array_1[$key], $value); } // 键存在且非数组,直接保留$array_1的值,无需操作 } return $merged; }
验证结果
优化后的函数可同时满足两个测试场景的需求:
- 测试用例1中,
some_one键保留$array_1的值,新增array_0、array_2键,array_1子数组递归保留原值; - 测试用例2中,$array_1的
array_key_1/2/3保留原值,同时添加$array_2的array_key_4/5键值对。
内容的提问来源于stack exchange,提问作者simon
相关产品推荐
相关产品推荐

