PHP合并含重复键数组并保留不同值的技术解决方案问询
嘿,这个需求我之前处理过,array_merge()确实会直接覆盖相同键的值,完全不符合咱们要保留差异的要求。不过先得提个关键知识点:PHP的关联数组不允许存在重复的键名,你给出的期望结果在实际运行中会被自动覆盖(后面的a键会替换掉前面的),所以咱们得调整下实现思路,下面给你几个可行的方案,按需选择:
方案一:将重复键的不同值合并为数组(最常用)
这个方案会把相同键的不同值整合到一个子数组里,相同值只保留一个,最终得到结构清晰的关联数组,非常适合后续的业务处理。
$x = array( "a" => "0123", "b" => "1234", "c" => "0123"); $y = array( "a" => "3210", "b" => "1234", "d" => "0123"); $result = []; // 先把旧数组的内容全部加入结果 foreach ($x as $key => $value) { $result[$key] = $value; } // 遍历新数组,处理差异 foreach ($y as $key => $value) { if (!isset($result[$key])) { // 键不存在,直接添加 $result[$key] = $value; } else { if ($result[$key] !== $value) { // 值不同,先把现有值转成数组(如果还不是的话) if (!is_array($result[$key])) { $result[$key] = [$result[$key]]; } // 避免重复添加相同值(如果不需要去重可以删掉这一步) if (!in_array($value, $result[$key])) { $result[$key][] = $value; } } // 值相同的话啥也不用做,保留原来的就行 } } print_r($result);
运行后输出:
Array ( [a] => Array ( [0] => 0123 [1] => 3210 ) [b] => 1234 [c] => 0123 [d] => 0123 )
方案二:用索引数组存储所有键值对(保留原始条目)
如果就是想完整保留每一个原始键值对,不管键是否重复,可以把每个键值对包装成子数组,存到索引数组里,这样就能看到所有原始条目:
$x = array( "a" => "0123", "b" => "1234", "c" => "0123"); $y = array( "a" => "3210", "b" => "1234", "d" => "0123"); $result = []; // 先添加旧数组的所有条目 foreach ($x as $key => $value) { $result[] = [$key => $value]; } // 添加新数组的条目,但跳过和旧数组中键值完全相同的 foreach ($y as $key => $value) { $isDuplicate = false; foreach ($result as $item) { if (array_key_exists($key, $item) && $item[$key] === $value) { $isDuplicate = true; break; } } if (!$isDuplicate) { $result[] = [$key => $value]; } } print_r($result);
运行后输出:
Array ( [0] => Array ( [a] => 0123 ) [1] => Array ( [b] => 1234 ) [2] => Array ( [c] => 0123 ) [3] => Array ( [a] => 3210 ) [4] => Array ( [d] => 0123 ) )
方案三:用array_reduce简化代码(函数式风格)
如果喜欢更简洁的写法,可以用array_reduce来合并逻辑,和方案一的效果完全一致,只是写法更偏向函数式编程:
$x = array( "a" => "0123", "b" => "1234", "c" => "0123"); $y = array( "a" => "3210", "b" => "1234", "d" => "0123"); // 把两个数组合并成一个键值对集合 $allItems = array_merge($x, $y); $result = array_reduce(array_keys($allItems), function($carry, $key) use ($allItems) { $value = $allItems[$key]; if (!isset($carry[$key])) { $carry[$key] = $value; } else { if ($carry[$key] !== $value) { $carry[$key] = is_array($carry[$key]) ? $carry[$key] : [$carry[$key]]; if (!in_array($value, $carry[$key])) { $carry[$key][] = $value; } } } return $carry; }, []); print_r($result);
这个方案的输出和方案一完全相同,适合习惯函数式写法的开发者。
内容的提问来源于stack exchange,提问作者goethe
相关产品推荐
相关产品推荐

