【问题标题】:How to merge two arrays by taking over only values from the second array that has the same keys as the first one?如何通过仅接收与第一个具有相同键的第二个数组中的值来合并两个数组?
【发布时间】:2011-09-27 14:00:15
【问题描述】:

我想合并两个数组:

$filtered = array(1 => 'a', 3 => 'c');
$changed = array(2 => 'b*', 3 => 'c*');

而合并应包括$filtered 的所有元素以及$changed 中在$filtered 中具有相应键的所有元素:

$merged = array(1 => 'a', 3 => 'c*');

array_merge($filtered, $changed) 也会将$changed 的附加键添加到$filtered 中。所以它并不适合。

我知道我可以使用$keys = array_intersect_key($filtered, $changed) 来获取两个数组中都存在的键,这已经完成了一半的工作。

但是我想知道是否有任何(本机)函数可以将$changed 数组减少为$keysarray_intersect_key 指定的数组?我知道我可以将array_filter 与回调函数一起使用并检查其中的$keys,但可能还有其他一些纯本机函数可以仅从可以指定键的数组中提取那些元素?

我之所以这么问,是因为原生函数通常比带有回调的 array_filter 快得多。

【问题讨论】:

    标签: php arrays filter array-merge array-key


    【解决方案1】:

    如果我正确理解您的逻辑,应该这样做:

    array_intersect_key($changed, $filtered) + $filtered
    

    实施:

    $filtered = array(1 => 'a', 3 => 'c');
    $changed = array(2 => 'b*', 3 => 'c*');
    $expected = array(1 => 'a', 3 => 'c*');    
    $actual = array_key_merge_deceze($filtered, $changed);
    
    var_dump($expected, $actual);
    
    function array_key_merge_deceze($filtered, $changed) {
        $merged = array_intersect_key($changed, $filtered) + $filtered;
        ksort($merged);
        return $merged;
    }
    

    输出:

    Expected:
    array(2) {
      [1]=>
      string(1) "a"
      [3]=>
      string(2) "c*"
    }
    
    Actual:
    array(2) {
      [1]=>
      string(1) "a"
      [3]=>
      string(2) "c*"
    }
    

    【讨论】:

    • 联合反对路口。但联合将添加 $filtered 的密钥以及 AFAIK。我试试看。
    • 朱普。我刚刚测试过,我的错;)。它工作得很好,只是键的顺序发生了变化,但这没问题,因为我将它们作为数字索引,所以 ksort 完成了这项工作。完美的。非常感谢!
    • @deceze array_intersect_key($changed, $filtered) + $filtered 奇怪。我以前从未见过。不知道这里发生了什么,但它有效! + $filtered的工作是什么
    • @array_intersect_key($changed, $filtered) 获取来自$changed 的所有值,这些值在$filtered 中有一个键,即它产生$filtered 的一个子集,其中的值来自$changed+ $filtered 然后将 $filtered 中的其余值添加回结果中,即它填充子集以使所有键都在 $filtered 中。
    • $filtered 为空时,您可能需要返回$changed,具体取决于您的用例。
    【解决方案2】:

    如果您希望第二个数组 ($b) 成为指示如果那里只有键的模式,那么您也可以试试这个

    $new_array =  array_intersect_key( $filtered, $changed ) + $changed;
    

    【讨论】:

      【解决方案3】:

      如果您的键是非数字的(您的不是,所以这不是您确切问题的解决方案),那么您可以使用这种技术:

      $filtered = array('a' => 'a', 'c' => 'c');
      $changed = array('b' => 'b*', 'c' => 'c*');
      
      $merged = array_slice(array_merge($filtered, $changed), 0, count($filtered));
      

      结果:

      Array
      (
          [a] => a
          [c] => c*
      )
      

      这是因为对于非数字键,array_merge 会覆盖现有键的值,并将 $changed 中的键附加到新数组的末尾。所以我们可以简单地丢弃合并数组末尾的任何键,而不是原始数组的计数。

      由于这适用于同一个问题,但具有不同的键类型,我想我会提供它。

      如果你将它与数字键一起使用,那么结果就是带有重新索引键的原始数组(在这种情况下为$filtered)(IE 就像你使用了array_values)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-11
        • 2022-11-12
        • 2021-06-05
        • 2012-03-31
        • 2022-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多