【问题标题】:Array_merge versus + [duplicate]Array_merge 与 + [重复]
【发布时间】:2011-10-26 22:43:05
【问题描述】:

当我将 array_merge() 与关联数组一起使用时,我得到了我想要的,但是当我将它们与数字键数组一起使用时,键会改变。

+ 保留了键,但它不适用于关联数组。

我不明白这是怎么回事,谁能给我解释一下?

【问题讨论】:

    标签: php arrays array-merge


    【解决方案1】:

    因为两个数组都是数字索引的,所以只会使用第一个数组中的值。

    + 运算符返回附加到左侧数组的右侧数组; 对于两个数组中都存在的键,将使用左侧数组中的元素,而忽略右侧数组中的匹配元素。

    http://php.net/manual/en/language.operators.array.php

    array_merge() 的行为略有不同:

    如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。 但是,如果数组包含数字键,则后面的值不会覆盖原始值,而是会被追加。输入数组中带有数字键的值将在结果数组中使用从零开始的递增键重新编号。

    http://php.net/manual/en/function.array-merge.php

    【讨论】:

    • 好吧 array_merge 是我想要的,但为什么它会改变数字索引?如果我将 array(1 => 'a', 2 => 'b') array(20 => 'x') 合并,我会得到一个 0, 1, 2 索引,而不是 1,2,20 :|
    • 因为它是这样写的。如果您在某些条件下需要不同的规则,您可能需要编写自己的函数来执行合并。
    • hm...所以+ 就像带有反向参数的array_merge,并且没有数字键重新编号?这意味着我只需要反转我的参数
    • 我正在编写的一些代码中的一位以前的开发人员在每个场合使用 + 来合并数组。如果您不确切知道它的作用,它会给其他人带来很多问题和过早脱发。答案也很好!
    • 在我们的代码库中,我们停止对数组使用 + 和 array_merge,而是使用我们编写的两个新函数。 “array_merge_by_key”和“array_concat”,而不是具有启发式的单个函数,试图猜测你想要什么
    【解决方案2】:

    这两个操作完全不同。

    数组加

    1. 数组加运算将所有数组视为关联数组。
    2. 在加号过程中发生键冲突时,将保留左(上一个)值
    3. null + array() 会引发致命错误

    array_merge()

    1. array_merge() 与 index-array 和 assoc-array 的工作方式不同。
    2. 如果两个参数都是索引数组,array_merge() 连接索引数组值。
    3. 如果不是,则 index-array 将转换为 values 数组,然后再转换为 assoc 数组。
    4. 现在它得到了两个关联数组并将它们合并在一起,当键冲突时,将保留右(最后一个)值。
    5. array_merge(null, array()) 返回 array() 并收到警告说,参数 #1 不是数组。

    我在下面发布代码以使事情清楚。

    function array_plus($a, $b){
        $results = array();
        foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
        foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
        return $results;
    }
    
    //----------------------------------------------------------------
    
    function is_index($a){
        $keys = array_keys($a);
        foreach($keys as $key) {
            $i = intval($key);
            if("$key"!="$i") return false;
        }
        return true;
    }
    
    function array_merge($a, $b){
        if(is_index($a)) $a = array_values($a);
        if(is_index($b)) $b = array_values($b);
        $results = array();
        if(is_index($a) and is_index($b)){
            foreach($a as $v) $results[] = $v;
            foreach($b as $v) $results[] = $v;
        }
        else{
            foreach($a as $k=>$v) $results[$k] = $v;
            foreach($b as $k=>$v) $results[$k] = $v;
        }
        return $results;
    }
    

    【讨论】:

    • 示例代码很棒,但是很难阅读。如果格式正确会好很多...
    • 确实,您的实现很棒,只是它没有提供与内置 array_merge 函数相同的结果。如果您想查看差异,请将运行var_dump(array_merge(['a' => 1, 'b' => 2, 3, 4], ['a' => 5, 'b' => 6, 7, 8])); 的结果与var_dump(your_array_merge(['a' => 1, 'b' => 2, 3, 4], ['a' => 5, 'b' => 6, 7, 8])); 进行比较(我已将您的实现重命名为your_array_merge 以避免函数重新定义)。不同之处在于,混合数组的数字和字符串键在原始实现中的处理方式不同。
    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 2018-06-30
    • 2011-06-07
    • 1970-01-01
    • 2017-09-19
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多