I never seem to remember all the differences and aspects of the array_merge() function and array concatenation (not even documented thoroughly). On top there is this array_merge_recursive() which behaves like array_merge() though.
To start with I’ll say that array() + array() (called array concatenation) is in general NOT the same as array_merge(). It may behave in the same way if your arrays have all keys different. In this case you get both function and operator return the same result:
Next step: the function and the operator differ in the way they process numeric indexes as opposed to string keys.
For numeric indexes:
· operator + is appending new numeric indexes to the end of array 1, but keeps the newly added indexes intact.
· array_merge() is appending second array values and reindexing all indexes starting from 0.
· both will NOT overwrite the values in array 1 with values of array 2.
For string indexes:
· operator + is NOT overwriting the values
· array_merge() is overwriting.
· both will not reindex string keys (this makes no sense, really).
· array_merge_recursive() is doing something unprecedented and undocumented though. For a value with the same key it’s making a sub-array with both values combined.
That’s why people create such an amount of custom merge functions like
· array_merge_recursive_distinct
· array_merge_recursive_leftsource
· array_merge_recursive_unique
· array_merge_recursive_keys
· array_merge_recursive_keep_keys
· array_merge_recursive2
· array_merge_replace
· array_merge_n
· array_merge_2
· array_merge_replace_recursive
all of which are described in the comments to http://www.php.net/manual/en/function.array-merge-recursive.php
As you see the choice of the way to combine arrays is not so trivial. I’ve tried to summarize the data into the following table.
Operation/Function | Source Data | Overwrite? | Reindex? | Recursive? | Compares | KeysOrder? |
array() + array() | Numeric | NO | No | Yes | Keys! | important |
array() + array() | Associative | NO | No | Yes | Keys! | important |
array_merge(a, a) | Numeric | NO!!! | YES | No, ? | Values! | |
array_merge(a, a) | Associative | Yes | NO | No, ? | Values! | |
array_merge_recursive | Numeric | Yes | ||||
array_merge_recursive | Associative | Yes |
This was much to hard for me to remember so I’ve made a function which serves most of my purposes and behaves consistently and conveniently:
· it preserves keys both indexes and string keys (no-reindexing)
· it overwrites values from array1 with values of array2 provided they have the same keys
· it works recursively as much as it can, but doesn’t create sub-arrays when source values are not arrays
· pretty simple and straightforward it is (probably too simple to be built-in into PHP).
Enjoy:
function array_merge_recursive_overwrite($ar1, $ar2) {
if (!is_array($ar1)) {
$ar1 = $ar2;
} else if (!is_array($ar2)) {
//return $ar1;
} else {
foreach ($ar2 as $key2 => $val2) {
$subindex = isset($ar1[$key2]) ? $ar1[$key2] : NULL;
$ar1[$key2] = array2::array_merge_recursive_overwrite($subindex, $val2);
}
}
return $ar1;
}
No comments:
Post a Comment