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
).
精彩评论