正如您毫无疑问地发现的那样,array_merge_recursive() 顽固地将所有数字或“数字字符串”键粉碎成一维数组。为避免这种行为,您需要将每个数组的初始键转换为字符串,而array_merge_recursive() 不会将其假定为数字。
此外,您还想过滤掉所有具有空值的元素。
我最初编写了一个单行程序,执行密钥重新转换然后过滤值,但这种方式效率较低。对于您的情况,您应该只在可能包含空值的数组上使用array_filter()。
输入数组:
$a=[1=>"sadsad@fsdf.fgh",2=>"rtt@RERT.FDG",3=>"WQEWQ@fgdg.h"];
$b=[1=>"",2=>"4234235",3=>""];
$c=[2=>1];
代码:
// remove empty values from all arrays that may have them
$b=array_filter($b,'strlen');
// for all arrays, cast numeric keys to string by prepending with a space
function addK($v){return " $v";}
$a=array_combine(array_map('addK',array_keys($a)),$a);
$b=array_combine(array_map('addK',array_keys($b)),$b);
$c=array_combine(array_map('addK',array_keys($c)),$c);
// merge arrays recursively
$merged=array_merge_recursive($a,$b,$c);
// cast keys back to numeric
$merged=array_combine(array_map('trim',array_keys($merged)),$merged);
// force all top-level elements to be arrays
foreach($merged as $k=>$v){
if(is_string($merged[$k])){$merged[$k]=[$v];}
}
var_export($merged);
输出:
array (
1 => array (
0 => 'sadsad@fsdf.fgh',
),
2 => array (
0 => 'rtt@RERT.FDG',
1 => '4234235',
2 => 1,
),
3 => array (
0 => 'WQEWQ@fgdg.h',
),
)
对于想知道array_merge_recursive()在没有准备的情况下运行时的区别的读者:
array (
0 => 'sadsad@fsdf.fgh',
1 => 'rtt@RERT.FDG',
2 => 'WQEWQ@fgdg.h',
3 => '',
4 => '4234235',
5 => '',
6 => 1,
)
注意到一维数组和重新索引的键了吗? ...对 OP 完全没用。
最后,对于任何想要将键重新转换为所有数组并希望使我的过程更加干燥的人,可能有机会设置可变参数函数或类似函数。我只是懒得去追求这个概念,因为我不想让我的答案变得复杂,而且重复我自己也不是很糟糕。