Possible Duplicate:
PHP: How to sum values of the array of the same key
I am looking for an array_merge()
function that does NOT replace values, but ADDS them.
Example, this is the code I am trying:
echo "<pre>"; $a1 = array( "a" => 2 ,"b" => 0 ,"c" => 5 ); $a2 = array( "a" => 3 ,"b" => 9 ,"c" => 7 ,"d" => 10 ); $a3 = array_merge($a1, $a2); print_r($a3);
Sadly, this outputs this:
Array ( [a] => 3 [b] => 9 [c] => 7 [d] => 10 )
I then tried, instead of array_merge
, just simply adding the two arrays
$a3 = $a1 + $a2;
But this outputs
Array ( [a] => 2 [b] => 0 [c] => 5 [d] => 10 )
What I truly want is to be able to pass as many arrays as needed, and then get their sum. So in my example, I want the output to be:
Array ( [a] => 5 [b] => 9 [c] => 12 [d] => 10 )
Of course I can schlepp and build some function with many foreach
etc, but am looking or a smarter, cleaner solution. Thanks for any pointers!
array_merge does merge two arrays while retaining all keys. But you want to sum the value of identical keys of two arrays, which is something else.
To merge elements from one array to another, we must first iterate(loop) through all the array elements. In the loop, we will retrieve each element from an array and insert(using the array push() method) to another array. Now, we can call the merge() function and pass two arrays as the arguments for merging.
array_merge() Function: The array_merge() function is used to merge two or more arrays into a single array. This function is used to merge the elements or values of two or more arrays together into a single array.
$sums = array(); foreach (array_keys($a1 + $a2) as $key) { $sums[$key] = (isset($a1[$key]) ? $a1[$key] : 0) + (isset($a2[$key]) ? $a2[$key] : 0); }
You could shorten this to the following using the error suppression operator, but it should be considered ugly:
$sums = array(); foreach (array_keys($a1 + $a2) as $key) { $sums[$key] = @($a1[$key] + $a2[$key]); }
Alternatively, some mapping:
$keys = array_fill_keys(array_keys($a1 + $a2), 0); $sums = array_map(function ($a1, $a2) { return $a1 + $a2; }, array_merge($keys, $a1), array_merge($keys, $a2));
Or sort of a combination of both solutions:
$sums = array_fill_keys(array_keys($a1 + $a2), 0); array_walk($sums, function (&$value, $key, $arrs) { $value = @($arrs[0][$key] + $arrs[1][$key]); }, array($a1, $a2));
I think these are concise enough to adapt one of them on the spot whenever needed, but to put it in terms of a function that accepts an unlimited number of arrays and sums them:
function array_sum_identical_keys() { $arrays = func_get_args(); $keys = array_keys(array_reduce($arrays, function ($keys, $arr) { return $keys + $arr; }, array())); $sums = array(); foreach ($keys as $key) { $sums[$key] = array_reduce($arrays, function ($sum, $arr) use ($key) { return $sum + @$arr[$key]; }); } return $sums; }
My contribution:
function array_merge_numeric_values() { $arrays = func_get_args(); $merged = array(); foreach ($arrays as $array) { foreach ($array as $key => $value) { if ( ! is_numeric($value)) { continue; } if ( ! isset($merged[$key])) { $merged[$key] = $value; } else { $merged[$key] += $value; } } } return $merged; }
Pass as many arrays to it as you want. Feel free to add some more defense, ability to accept multidimensional arrays, or type checking.
Demo: http://codepad.org/JG6zwAap
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With