Skip to content

Instantly share code, notes, and snippets.

@Nickology
Last active August 1, 2021 17:17
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Nickology/f700e319cbafab5eaedc to your computer and use it in GitHub Desktop.
Save Nickology/f700e319cbafab5eaedc to your computer and use it in GitHub Desktop.
[PHP] Merge N arrays AND sum numeric values of identical keys
<?php
/**
* array_merge_recursive_numeric function. Merges N arrays into one array AND sums the values of identical keys.
* WARNING: If keys have values of different types, the latter values replace the previous ones.
*
* Example:
*
* $a = array( "A" => "bob", "sum" => 10, "C" => array("x","y","z" => 50) );
* $b = array( "A" => "max", "sum" => 12, "C" => array("x","y","z" => 45) );
* $c = array( "A" => "tom", "sum" => 8, "C" => array("x","y","z" => 50, "w" => 1) );
*
* print_r(array_merge_recursive_numeric($a,$b,$c));
*
* Result:
*
* Array
* (
* [A] => tom
* [sum] => 18
* [C] => Array
* (
* [0] => x
* [1] => y
* [z] => 100
* [w] => 1
* )
* )
*
* Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc
* @params N arrays (all parameters must be arrays)
* @author Nick Jouannem <nick@nickology.com>
* @access public
* @return void
*/
function array_merge_recursive_numeric() {
// Gather all arrays
$arrays = func_get_args();
// If there's only one array, it's already merged
if (count($arrays)==1) {
return $arrays[0];
}
// Remove any items in $arrays that are NOT arrays
foreach($arrays as $key => $array) {
if (!is_array($array)) {
unset($arrays[$key]);
}
}
// We start by setting the first array as our final array.
// We will merge all other arrays with this one.
$final = array_shift($arrays);
foreach($arrays as $b) {
foreach($final as $key => $value) {
// If $key does not exist in $b, then it is unique and can be safely merged
if (!isset($b[$key])) {
$final[$key] = $value;
} else {
// If $key is present in $b, then we need to merge and sum numeric values in both
if ( is_numeric($value) && is_numeric($b[$key]) ) {
// If both values for these keys are numeric, we sum them
$final[$key] = $value + $b[$key];
} else if (is_array($value) && is_array($b[$key])) {
// If both values are arrays, we recursively call ourself
$final[$key] = array_merge_recursive_numeric($value, $b[$key]);
} else {
// If both keys exist but differ in type, then we cannot merge them.
// In this scenario, we will $b's value for $key is used
$final[$key] = $b[$key];
}
}
}
// Finally, we need to merge any keys that exist only in $b
foreach($b as $key => $value) {
if (!isset($final[$key])) {
$final[$key] = $value;
}
}
}
return $final;
}
?>
@germanow
Copy link

Thanks for great job! I think return type should be array instead of void.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment