数组合并相同的键

时间:2017-04-26 10:37:12

标签: php arrays multidimensional-array array-merge

我有这三个数组:

Array
(
    [1] => sadsad@fsdf.fgh
    [2] => rtt@RERT.FDG
    [3] => WQEWQ@fgdg.h
)

Array
(
    [1] => 
    [2] => 4234235
    [3] => 
)

Array
(
    [2] => 1
)

我想生成这个输出:

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_merge(),但我无法得到正确的结果。

如果我需要使用foreach()我必须做什么来合并这3个数组。

2 个答案:

答案 0 :(得分:4)

写了一个小脚本:

$a = array
(
    1=>"sadsad@fsdf.fgh",
    2=>"rtt@RERT.FDG",
    3=>"WQEWQ@fgdg.h",
);

$b = array
(
    2 => 4234235 
);

$c = array
(
    2 => 1
);

$arrayKeys = array_unique(
    array_merge(
        array_keys($a),
        array_keys($b),
        array_keys($c)
    )
);

$d = array_combine(
    $arrayKeys,
    array_fill(
        0,
        count($arrayKeys),
        array()
    )
);

foreach($a as $key => $value) {
    if(!empty($a[$key])) {
        $d[$key][] = $a[$key];
    }
    if(!empty($b[$key])) {
        $d[$key][] = $b[$key];
    }
    if(!empty($c[$key])) {
        $d[$key][] = $c[$key];
    }
}
var_dump($d);

此外,如果您愿意,可以仅使用变量名称将数组合并在一起

//names of the variables to merge together
$arrayVariableNames = array("a","b","c");

//merging array keys together
$arrayKeys = array();
foreach($arrayVariableNames as $variableName) {
    $arrayKeys = array_merge(
        $arrayKeys,
        array_keys(${$variableName})
    );
}
$arrayKeys = array_unique($arrayKeys);

//initialize the result array with empty arrays
$resultArray = array_combine(
    $arrayKeys,
    array_fill(
        0,
        count($arrayKeys),
        array()
    )
);

//loop through all the keys and add the elements from all the arrays
foreach($resultArray as $key => &$value) {
    foreach($arrayVariableNames as $variableName) {
        if(!empty(${$variableName}[$key])) {
            $value[] = ${$variableName}[$key];
        }
    }
}

答案 1 :(得分:1)

正如您无疑发现的那样,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,
)

注意1d数组和重新索引的键? ...... OP完全没用。

最后,对于任何想要将密钥重新转换为所有数组并希望使我的进程更加干燥的人,可能有机会设置可变参数函数或类似函数。我只是没有理会去追求这个概念,因为我不想让我的答案变得复杂,而且重复我自己并不是很可怕。