开发者

How to merge two arrays by taking over only values from the second array that has the same keys as the first one?

I'd like to merge two arrays with each other:

$filtered = a开发者_运维技巧rray(1 => 'a', 3 => 'c');
$changed = array(2 => 'b*', 3 => 'c*');

Whereas the merge should include all elements of $filtered and all those elements of $changed that have a corresponding key in $filtered:

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

array_merge($filtered, $changed) would add the additional keys of $changed into $filtered as well. So it does not really fit.

I know that I can use $keys = array_intersect_key($filtered, $changed) to get the keys that exist in both arrays which is already half of the work.

However I'm wondering if there is any (native) function that can reduce the $changed array into an array with the $keys specified by array_intersect_key? I know I can use array_filter with a callback function and check against $keys therein, but there is probably some other purely native function to extract only those elements from an array of which the keys can be specified?

I'm asking because the native functions are often much faster than array_filter with a callback.


This should do it, if I'm understanding your logic correctly:

array_intersect_key($changed, $filtered) + $filtered

Implementation:

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

Output:

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

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


if you want the second array ($b) to be the pattern that indicates that if there is only the key there, then you could also try this

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


If your keys are non-numeric (which yours are not, so this is not a solution to your exact question), then you can use this technique:

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

$merged = array_slice(array_merge($filtered, $changed), 0, count($filtered));

Result:

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

This works because for non-numeric keys, array_merge overwrites values for existing keys, and appends the keys in $changed to the end of the new array. So we can simply discard any keys from the end of the merged array more than the count of the original array.

Since this applies to the same question but with different key types I thought I'd provide it.

If you use this with numeric keys then the result is simply the original array ($filtered in this case) with re-indexed keys (IE as if you used array_values).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜