【问题标题】:Array merge with same keys具有相同键的数组合并
【发布时间】:2017-04-26 10:37:12
【问题描述】:

我有这三个数组:

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 个数组。

【问题讨论】:

    标签: php arrays multidimensional-array array-merge


    【解决方案1】:

    写了一个小脚本:

    $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];
            }
        }
    }
    

    【讨论】:

    • 如果$b$c 数组的值多于$a 数组怎么办?
    【解决方案2】:

    正如您毫无疑问地发现的那样,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 完全没用。

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

    【讨论】:

    • 我很喜欢katona.abel的方法,他们很聪明。不过还是有几点不同。第一种方法授予数组$a 的循环权限,然后OP 评论要求一种新方法允许$b 和$c 中的更多元素。第二种方法(我不太容易遵循它,但它确实使用可变变量来完成 array_merge_recursive() 的设计目的。我进行了一些测试,katona 的第二种方法似乎并没有破坏——好的编码!如果有人能在我们的任何一种方法中发现缺陷,请给我们留言。
    猜你喜欢
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多