This question already has answers here:
Merge two indexed arrays of indexed arrays based on first column value
(2 answers)
Closed 5 months ago.
I need to compare two 2D arrays in PHP. The arrays look like this:
Array one
ID Name
11 Aa
11 Ab
12 Bb
13 Cc
14 Dd
15 Ee
Array two
ID Content
11 Cat
13 Dog
14 Donkey
Now I'd need to combine these two into an array like this:
ID Name Conent
11 Aa Cat
11 Ab Cat
12 Bb
13 Cc Dog
14 Dd Donkey
15 Ee
How can I accomplish this? I have had no luck with array_merge() or $array3 = $array1 + $array2;
A quick way would be to iterate over the first array and append the value from the second:
$array1 = array('11' => 'Aa', '12' => 'Bb', '13' => 'Cc', '14' => 'Dd', '15' => 'Ee');
$array2 = array('11' => 'Cat', '13' => 'Dog', '14' => 'Donkey');
$combined = array();
foreach ($array1 as $key => $val) {
$combined[$key] = $val . (isset($array2[$key]) ? ' '.$array2[$key] : '');
}
This will loop through every key/value in $array1 and add it to the $combined array. If a value in $array2 exists with the same index, it will append it to that value from $array1, separated with a space.
UPDATE: I misread the format of the arrays (again). I assumed ID was the actual index in the array, but as the example array output has both Name and Content, I'm assuming ID is an actual index string value and not the index in the array itself. To stick with the loop scenario, you can iterate through the first array and have a nested loop iterate through the second:
$array1 = array(
array('ID' => '11', 'Name' => 'Aa'),
array('ID' => '12', 'Name' => 'Bb'),
array('ID' => '13', 'Name' => 'Cc'),
array('ID' => '14', 'Name' => 'Dd'),
array('ID' => '15', 'Name' => 'Ee'),
);
$array2 = array(
array('ID' => '11', 'Content' => 'Cat'),
array('ID' => '13', 'Content' => 'Dog'),
array('ID' => '14', 'Content' => 'Donkey')
);
$combined = array();
foreach ($array1 as $arr) {
$comb = array('ID' => $arr['ID'], 'Name' => $arr['Name'], 'Content' => '');
foreach ($array2 as $arr2) {
if ($arr2['ID'] == $arr['ID']) {
$comb['Content'] = $arr2['Content'];
break;
}
}
$combined[] = $comb;
}
This will add every value in $array1 to the combined array and if, and only if, a value in $array2 contains the same ID field will it add it's Content field to the array too. This can be extended to handle any number of fields as well, either by name, or by changing the inner-if block to have $comb += $arr2; instead (which should merge all non-existing indexes).
You will have to make your own function:
function putThemTogether($array1, $array2) {
$output = array();
foreach($array1 as $key => $value) {
if (!isset($output[$key]))
$output[$key] = array();
$output[$key][] = $value;
}
foreach($array2 as $key => $value) {
if (!isset($output[$key]))
$output[$key] = array();
$output[$key][] = $value;
}
return $output;
}
To make this better you could make it take an arbitrary number of arguments.
$result = array_map (
function ($item) { return is_array($item) ? implode(' ', $item) : $item; },
array_merge_recursive($array1, $array2);
);
Note, that both arrays require string keys
Another solution for this is to use array_search and array_column (since PHP 5.5.0).
foreach ($array1 as $key => $val) {
$found_key = array_search($val['ID'], array_column($array2, 'ID'));
if ($found_key !== false) { $array1[$key]['Content'] = $array2[$found_key]['Content']; }
}
Try this I hope It'll work
function merge_two_arrays($array1,$array2) {
$data = array();
$arrayAB = array_merge($array1,$array2);
foreach ($arrayAB as $value) {
// This assumes there is a field called "id"
$id = $value['id'];
if (!isset($data[$id])) {
$data[$id] = array();
}
$data[$id] = array_merge($data[$id],$value);
}
return $data;
}
$master_array = merge_two_arrays($array1,$array2);
Related
How can I add all the columnar values by associative key? Note that key sets are dynamic.
Input array:
Array
(
[0] => Array
(
[gozhi] => 2
[uzorong] => 1
[ngangla] => 4
[langthel] => 5
)
[1] => Array
(
[gozhi] => 5
[uzorong] => 0
[ngangla] => 3
[langthel] => 2
)
[2] => Array
(
[gozhi] => 3
[uzorong] => 0
[ngangla] => 1
[langthel] => 3
)
)
Desired result:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
You can use array_walk_recursive() to get a general-case solution for your problem (the one when each inner array can possibly have unique keys).
$final = array();
array_walk_recursive($input, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
Example with array_walk_recursive() for the general case
Also, since PHP 5.5 you can use the array_column() function to achieve the result you want for the exact key, [gozhi], for example :
array_sum(array_column($input, 'gozhi'));
Example with array_column() for the specified key
If you want to get the total sum of all inner arrays with the same keys (the desired result that you've posted), you can do something like this (bearing in mind that the first inner array must have the same structure as the others) :
$final = array_shift($input);
foreach ($final as $key => &$value){
$value += array_sum(array_column($input, $key));
}
unset($value);
Example with array_column() in case all inner arrays have the same keys
If you want a general-case solution using array_column() then at first you may consider to get all unique keys , and then get the sum for each key :
$final = array();
foreach($input as $value)
$final = array_merge($final, $value);
foreach($final as $key => &$value)
$value = array_sum(array_column($input, $key));
unset($value);
Example with array_column() for the general case
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
isset($sumArray[$id]) || $sumArray[$id] = 0;
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
Use this snippet:
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Here is a solution similar to the two others:
$acc = array_shift($arr);
foreach ($arr as $val) {
foreach ($val as $key => $val) {
$acc[$key] += $val;
}
}
But this doesn’t need to check if the array keys already exist and doesn’t throw notices neither.
It can also be done using array_map :
$rArray = array(
0 => array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
),
1 => array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
),
2 => array(
'gozhi' => 3,
'uzorong' => 0,
'ngangla' => 1,
'langthel' => 3
),
);
$sumResult = call_user_func_array('array_map', array_merge(['sum'], $rArray));
function sum()
{
return array_sum(func_get_args());
}
$newarr=array();
foreach($arrs as $value)
{
foreach($value as $key=>$secondValue)
{
if(!isset($newarr[$key]))
{
$newarr[$key]=0;
}
$newarr[$key]+=$secondValue;
}
}
Another version, with some benefits below.
$sum = ArrayHelper::copyKeys($arr[0]);
foreach ($arr as $item) {
ArrayHelper::addArrays($sum, $item);
}
class ArrayHelper {
public function addArrays(Array &$to, Array $from) {
foreach ($from as $key=>$value) {
$to[$key] += $value;
}
}
public function copyKeys(Array $from, $init=0) {
return array_fill_keys(array_keys($from), $init);
}
}
I wanted to combine the best of Gumbo's, Graviton's, and Chris J's answer with the following goals so I could use this in my app:
a) Initialize the 'sum' array keys outside of the loop (Gumbo). Should help with performance on very large arrays (not tested yet!). Eliminates notices.
b) Main logic is easy to understand without hitting the manuals. (Graviton, Chris J).
c) Solve the more general problem of adding the values of any two arrays with the same keys and make it less dependent on the sub-array structure.
Unlike Gumbo's solution, you could reuse this in cases where the values are not in sub arrays. Imagine in the example below that $arr1 and $arr2 are not hard-coded, but are being returned as the result of calling a function inside a loop.
$arr1 = array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
);
$arr2 = array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
);
$sum = ArrayHelper::copyKeys($arr1);
ArrayHelper::addArrays($sum, $arr1);
ArrayHelper::addArrays($sum, $arr2);
It can also be done using array_walk:
function array_sum_values(array $input, $key) {
$sum = 0;
array_walk($input, function($item, $index, $params) {
if (!empty($item[$params[1]]))
$params[0] += $item[$params[1]];
}, array(&$sum, $key)
);
return $sum;
}
var_dump(array_sum_values($arr, 'gozhi'));
Not so readable like previous solutions but it works :)
Go through each item of the array and sum values to previous values if they exist, if not just assign the value.
<?php
$array =
[
[
'a'=>1,
'b'=>1,
'c'=>1,
],
[
'a'=>2,
'b'=>2,
],
[
'a'=>3,
'd'=>3,
]
];
$result = array_reduce($array, function($carry, $item) {
foreach($item as $k => $v)
$carry[$k] = $v + ($carry[$k] ?? 0);
return $carry;
}, []);
print_r($result);
Output:
Array
(
[a] => 6
[b] => 3
[c] => 1
[d] => 3
)
Or just loop through each sub array, and group the values for each column. Eventually summing them:
foreach($array as $subarray)
foreach($subarray as $key => $value)
$grouped[$key][] = $value;
$sums = array_map('array_sum', $grouped);
Here's a version where the array keys may not be the same for both arrays, but you want them all to be there in the final array.
function array_add_by_key( $array1, $array2 ) {
foreach ( $array2 as $k => $a ) {
if ( array_key_exists( $k, $array1 ) ) {
$array1[$k] += $a;
} else {
$array1[$k] = $a;
}
}
return $array1;
}
We need to check first if array key does exist.
CODE:
$sum = array();
foreach ($array as $key => $sub_array) {
foreach ($sub_array as $sub_key => $value) {
//If array key doesn't exists then create and initize first before we add a value.
//Without this we will have an Undefined index error.
if( ! array_key_exists($sub_key, $sum)) $sum[$sub_key] = 0;
//Add Value
$sum[$sub_key]+=$value;
}
}
print_r($sum);
OUTPUT With Array Key Validation:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
OUTPUT Without Array Key Validation:
Notice: Undefined index: gozhi in F:\web\index.php on line 37
Notice: Undefined index: uzorong in F:\web\index.php on line 37
Notice: Undefined index: ngangla in F:\web\index.php on line 37
Notice: Undefined index: langthel in F:\web\index.php on line 37
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
This is a bad practice although it prints the output. Always check first if key does exist.
Simple example with array_reduce()
$numbers = [10,20,30];
$total = 0;
foreach ($numbers as $number) {
$total += $number;
}
echo $total; // 60
=>
$numbers = [10,20,30];
$total = array_reduce($numbers, function ($previous, $current) {
return $previous + $current;
});
echo $total; // 60
With assoc array:
$carts = [
['item' => 'A', 'qty' => 2, 'price' => 10],
['item' => 'B', 'qty' => 3, 'price' => 20],
['item' => 'C', 'qty' => 5, 'price' => 30]
];
$total = array_reduce(
$carts,
function ($prev, $item) {
return $prev + $item['qty'] * $item['price'];
}
);
echo $total; // 155
More info => https://www.phptutorial.net/php-tutorial/php-array_reduce/
For those who landed here and are searching for a solution that merges N arrays AND also sums the values of identical keys found in the N arrays, I've written this function that works recursively as well. (See: https://gist.github.com/Nickology/f700e319cbafab5eaedc)
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));
Will result in:
Array
(
[A] => tom
[sum] => 30
[C] => Array
(
[0] => x
[1] => y
[z] => 145
[w] => 1
)
)
Here's the code:
<?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.
*
* 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;
}
?>
Here you have how I usually do this kind of operations.
// We declare an empty array in wich we will store the results
$sumArray = array();
// We loop through all the key-value pairs in $myArray
foreach ($myArray as $k=>$subArray) {
// Each value is an array, we loop through it
foreach ($subArray as $id=>$value) {
// If $sumArray has not $id as key we initialize it to zero
if(!isset($sumArray[$id])){
$sumArray[$id] = 0;
}
// If the array already has a key named $id, we increment its value
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
You can try this:
$c = array_map(function () {
return array_sum(func_get_args());
},$a, $b);
and finally:
print_r($c);
this works great on my laravel project
print_r($Array); // your original array
$_SUM = [];
// count($Array[0]) => if the number of keys are equall in all arrays then do a count of index 0 etc.
for ($i=0; $i < count($Array[0]); $i++) {
$_SUM[] = $Array[0][$i] + $Array[1][$i]; // do a for loop on the count
}
print_r($_SUM); // get a sumed up array
$sumArray = array();
foreach ($myArray as $k => $subArray) {
foreach ($subArray as $id => $value) {
if (!isset($sumArray[$id])) {
$sumArray[$id] = 0;
}
$sumArray[$id]+=$value;
}
}
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
if(!isset($sumArray[$id])){
$sumArray[$id] =$value;
}else {
$sumArray[$id]+=$value;
}
}
}
print_r($sumArray);
`
For example, you can pluck all fields from a result like this below.
I am picking out the 'balance' from an array and save to a variable
$kii = $user->pluck('balance');
then on the next line u can sum like this:
$sum = $kii->sum();
Hope it helps.
Code here:
$temp_arr = [];
foreach ($a as $k => $v) {
if(!is_null($v)) {
$sum = isset($temp_arr[$v[0]]) ? ((int)$v[5] + $sum) : (int)$v[5];
$temp_arr[$v[0]] = $sum;
}
}
return $temp_arr;
Result:
{SEQ_OK: 1328,SEQ_ERROR: 561}
How to check two arrays and search for matching keys and merge the values of the 1st array with the matching keys of the second array.Please help me as I'm new to this.
example :
1st array = {id => 11,name => 'name',age => 18 }
2nd array = {id,name,age,school}
I want to get the result by adding the matching values to the 2nd array
2nd array = {id => 11,name => 'name',age => 18,school => }
try this
$a = ['id' => 11,'name' => 'name','age' => 18];
$b = array_flip(['id','name','age','school']);
foreach($b as $key => &$value){
$value = '';
}
$result = array_merge($b, $a);
One of the simple way is looping
$first= array('id' => 11,'name' => 'name','age' => 18 );
$second = array('id','name','age','school');
foreach ($second as $value) {
if(isset($first[$value])){
$final[$value] = $first[$value];
}
};
print_r($final);
Second Array flip and array merge
$first = ['id' => 11,'name' => 'name','age' => 18];
$second= array_flip(['id','name','age','school']);
foreach($second as $key => s$value){
$value = '';
}
$result = array_merge($second, $first);
print_r($result);
Use array_merge
<?php
$array1 = array('id' => '11', 'name' => 'name', 'age' => 18);
$array2 = array('id','name','age','school');
$array3 = array_merge(array_fill_keys($array2, null), $array1);
print_r($array3);
?>
I have an array that may look like
$arr = array(
array(
'test1' => 'testing1'
),
array(
'test2' => array(
1 =>'testing2
)
);
and I want to turn it into
$newArr = array(
'test1' => 'testing1',
'test2' => array(
1 => 'testing2'
)
);
so i have been trying to shift all array elements up one level.
eidt:
this is my method that combines 2 array together:
public function arrayMerge($arr1, $arr2)
{
foreach($arr2 as $key => $value) {
$condition = (array_key_exists($key, $arr1) && is_array($value));
$arr1[$key] = ($condition ? $this->arrayMerge($arr1[$key], $arr2[$key]) : $value);
}
return $arr1;
}
It's somewhat trivial, many ways are possible.
For example using the array union operator (+)Docs creating the union of all arrays inside the array:
$newArr = array();
foreach ($arr as $subarray)
$newArr += $subarray;
Or by using array_mergeDocs with all subarrays at once via call_user_func_arrayDocs:
$newArray = call_user_func_array('array_merge', $arr);
Try
$arr = array(
array('test1' => 'testing1' ),
array('test2' => array(1 =>'testing2'))
);
$new = array();
foreach($arr as $value) {
$new += $value;
}
var_dump($new);
Output
array
'test1' => string 'testing1' (length=8)
'test2' =>
array
1 => string 'testing2' (length=8)
I know this is quite easily accomplished with a foreach, then a while->list, etc procedure, (I have already accomplished it), however I sense that my code is a bit dirty and it doesn't look like the best solution... I'm looking to use native PHP array functions to do the following:
I have two arrays that look like this:
[
['rank' => '579', 'id' => '1'],
['rank' => '251', 'id' => '2'],
]
and
[
['size' => 'S', 'status' => 'A', 'id' => '1'],
['size' => 'L', 'status' => 'A', 'id' => '2'],
]
And I need merge them to produce:
[
['size' => 'S', 'status' => 'A', 'id' => '1', 'rank' => '579'],
['size' => 'L', 'status' => 'A', 'id' => '2', 'rank' => '251'],
]
Is there a way to be able to merge two arrays with the id value (or any other) without going into a endless set of foreachs?
Use array_merge_recursive()
$array = array_merge_recursive($array1, $array2);
or make your own function (it may be faster)
function my_array_merge(&$array1, &$array2) {
$result = Array();
foreach($array1 as $key => &$value) {
$result[$key] = array_merge($value, $array2[$key]);
}
return $result;
}
$array = my_array_merge($array1, array2);
print_r($array);
As Ray noticed in a comment, the accepted answer does not actually answer the question. I was unable to find an answer, so I created the following small utility function:
function array_merge_callback($array1, $array2, $predicate) {
$result = array();
foreach ($array1 as $item1) {
foreach ($array2 as $item2) {
if ($predicate($item1, $item2)) {
$result[] = array_merge($item1, $item2);
}
}
}
return $result;
}
Use it as follows:
array_merge_callback($array1, $array2, function ($item1, $item2) {
return $item1['id'] == $item2['id'];
});
Have a nice one to merging arrays like another languages.
It's because php have auto numbering array elements, and merging will dublicate or replace different elements by keys.
Now, it's changed.
// array_fork
public static function array_fork() {
$args = func_get_args();
$result = array();
foreach ($args as $arr) {
is_array($arr) || exit('[' . __METHOD__ . '] Each item must be an array.');
foreach ($arr as $key => $val) {
if (is_array($val)) {
// recursion
!isset($result[$key]) && $result[$key] = array();
$result[$key] = self::array_fork($result[$key], $arr[$key]);
continue;
}
if (is_numeric($key)) {
if (!in_array($arr[$key], $result))
$result[] = $arr[$key];
} else
$result[$key] = $arr[$key];
}
}
return $result;
}
function custom_array_merge(&$array1, &$array2) {
$result = Array();
foreach ($array1 as $key_1 => &$value_1) {
// if($value['name'])
foreach ($array2 as $key_1 => $value_2) {
if($value_1['name'] == $value_2['name']) {
$result[] = array_merge($value_1,$value_2);
}
}
}
return $result;
}
// Pass $array1, &$array2 and change the $value_2['name'] // name based on which u want to merge.
ok, let's suppost your arrays are called $arr1 and $arr2, you could do this:
<?php
$newarray = Array();
foreach ($arr1 as $element=>$value){
$newarray = array_merge($arr1[$element],$arr2[$element])
}
?>
It is not necessary to use a recursive technique nor multiple loops. Merge the two arrays together, then assign temporary first-level keys in the output array based on the rows' id value. If the id is being encountered for the first time, merge the row's data with an empty array; otherwise merge the pre-existing row data from result array. To remove the first-level keys after looping, call array_values().
Code: (Demo)
$a = [
['rank' => '579', 'id' => '1'],
['rank' => '251', 'id' => '2'],
];
$b = [
['size' => 'S', 'status' => 'A', 'id' => '1'],
['size' => 'L', 'status' => 'A', 'id' => '2'],
];
$result = [];
foreach (array_merge($a, $b) as $row) {
$result[$row['id']] = $row + ($result[$row['id']] ?? []);
}
var_export(array_values($result));
Not represented by the question's sample data, if the two data sets have columnar data collisions in their respective id group, then later encountered values will overwrite earlier stored values. Demo To reverse that behavior, you can simply swap the data on either side of the "array union operator". Demo Be warned that array union is suitable in this case because the rows contain non-numeric keys. For other scenarios, it may be more reliable to use array_merge() or array_replace() instead of the union operator.
How can I add all the columnar values by associative key? Note that key sets are dynamic.
Input array:
Array
(
[0] => Array
(
[gozhi] => 2
[uzorong] => 1
[ngangla] => 4
[langthel] => 5
)
[1] => Array
(
[gozhi] => 5
[uzorong] => 0
[ngangla] => 3
[langthel] => 2
)
[2] => Array
(
[gozhi] => 3
[uzorong] => 0
[ngangla] => 1
[langthel] => 3
)
)
Desired result:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
You can use array_walk_recursive() to get a general-case solution for your problem (the one when each inner array can possibly have unique keys).
$final = array();
array_walk_recursive($input, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
Example with array_walk_recursive() for the general case
Also, since PHP 5.5 you can use the array_column() function to achieve the result you want for the exact key, [gozhi], for example :
array_sum(array_column($input, 'gozhi'));
Example with array_column() for the specified key
If you want to get the total sum of all inner arrays with the same keys (the desired result that you've posted), you can do something like this (bearing in mind that the first inner array must have the same structure as the others) :
$final = array_shift($input);
foreach ($final as $key => &$value){
$value += array_sum(array_column($input, $key));
}
unset($value);
Example with array_column() in case all inner arrays have the same keys
If you want a general-case solution using array_column() then at first you may consider to get all unique keys , and then get the sum for each key :
$final = array();
foreach($input as $value)
$final = array_merge($final, $value);
foreach($final as $key => &$value)
$value = array_sum(array_column($input, $key));
unset($value);
Example with array_column() for the general case
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
isset($sumArray[$id]) || $sumArray[$id] = 0;
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
Use this snippet:
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Here is a solution similar to the two others:
$acc = array_shift($arr);
foreach ($arr as $val) {
foreach ($val as $key => $val) {
$acc[$key] += $val;
}
}
But this doesn’t need to check if the array keys already exist and doesn’t throw notices neither.
It can also be done using array_map :
$rArray = array(
0 => array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
),
1 => array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
),
2 => array(
'gozhi' => 3,
'uzorong' => 0,
'ngangla' => 1,
'langthel' => 3
),
);
$sumResult = call_user_func_array('array_map', array_merge(['sum'], $rArray));
function sum()
{
return array_sum(func_get_args());
}
$newarr=array();
foreach($arrs as $value)
{
foreach($value as $key=>$secondValue)
{
if(!isset($newarr[$key]))
{
$newarr[$key]=0;
}
$newarr[$key]+=$secondValue;
}
}
Another version, with some benefits below.
$sum = ArrayHelper::copyKeys($arr[0]);
foreach ($arr as $item) {
ArrayHelper::addArrays($sum, $item);
}
class ArrayHelper {
public function addArrays(Array &$to, Array $from) {
foreach ($from as $key=>$value) {
$to[$key] += $value;
}
}
public function copyKeys(Array $from, $init=0) {
return array_fill_keys(array_keys($from), $init);
}
}
I wanted to combine the best of Gumbo's, Graviton's, and Chris J's answer with the following goals so I could use this in my app:
a) Initialize the 'sum' array keys outside of the loop (Gumbo). Should help with performance on very large arrays (not tested yet!). Eliminates notices.
b) Main logic is easy to understand without hitting the manuals. (Graviton, Chris J).
c) Solve the more general problem of adding the values of any two arrays with the same keys and make it less dependent on the sub-array structure.
Unlike Gumbo's solution, you could reuse this in cases where the values are not in sub arrays. Imagine in the example below that $arr1 and $arr2 are not hard-coded, but are being returned as the result of calling a function inside a loop.
$arr1 = array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
);
$arr2 = array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
);
$sum = ArrayHelper::copyKeys($arr1);
ArrayHelper::addArrays($sum, $arr1);
ArrayHelper::addArrays($sum, $arr2);
It can also be done using array_walk:
function array_sum_values(array $input, $key) {
$sum = 0;
array_walk($input, function($item, $index, $params) {
if (!empty($item[$params[1]]))
$params[0] += $item[$params[1]];
}, array(&$sum, $key)
);
return $sum;
}
var_dump(array_sum_values($arr, 'gozhi'));
Not so readable like previous solutions but it works :)
Go through each item of the array and sum values to previous values if they exist, if not just assign the value.
<?php
$array =
[
[
'a'=>1,
'b'=>1,
'c'=>1,
],
[
'a'=>2,
'b'=>2,
],
[
'a'=>3,
'd'=>3,
]
];
$result = array_reduce($array, function($carry, $item) {
foreach($item as $k => $v)
$carry[$k] = $v + ($carry[$k] ?? 0);
return $carry;
}, []);
print_r($result);
Output:
Array
(
[a] => 6
[b] => 3
[c] => 1
[d] => 3
)
Or just loop through each sub array, and group the values for each column. Eventually summing them:
foreach($array as $subarray)
foreach($subarray as $key => $value)
$grouped[$key][] = $value;
$sums = array_map('array_sum', $grouped);
Here's a version where the array keys may not be the same for both arrays, but you want them all to be there in the final array.
function array_add_by_key( $array1, $array2 ) {
foreach ( $array2 as $k => $a ) {
if ( array_key_exists( $k, $array1 ) ) {
$array1[$k] += $a;
} else {
$array1[$k] = $a;
}
}
return $array1;
}
We need to check first if array key does exist.
CODE:
$sum = array();
foreach ($array as $key => $sub_array) {
foreach ($sub_array as $sub_key => $value) {
//If array key doesn't exists then create and initize first before we add a value.
//Without this we will have an Undefined index error.
if( ! array_key_exists($sub_key, $sum)) $sum[$sub_key] = 0;
//Add Value
$sum[$sub_key]+=$value;
}
}
print_r($sum);
OUTPUT With Array Key Validation:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
OUTPUT Without Array Key Validation:
Notice: Undefined index: gozhi in F:\web\index.php on line 37
Notice: Undefined index: uzorong in F:\web\index.php on line 37
Notice: Undefined index: ngangla in F:\web\index.php on line 37
Notice: Undefined index: langthel in F:\web\index.php on line 37
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
This is a bad practice although it prints the output. Always check first if key does exist.
Simple example with array_reduce()
$numbers = [10,20,30];
$total = 0;
foreach ($numbers as $number) {
$total += $number;
}
echo $total; // 60
=>
$numbers = [10,20,30];
$total = array_reduce($numbers, function ($previous, $current) {
return $previous + $current;
});
echo $total; // 60
With assoc array:
$carts = [
['item' => 'A', 'qty' => 2, 'price' => 10],
['item' => 'B', 'qty' => 3, 'price' => 20],
['item' => 'C', 'qty' => 5, 'price' => 30]
];
$total = array_reduce(
$carts,
function ($prev, $item) {
return $prev + $item['qty'] * $item['price'];
}
);
echo $total; // 155
More info => https://www.phptutorial.net/php-tutorial/php-array_reduce/
For those who landed here and are searching for a solution that merges N arrays AND also sums the values of identical keys found in the N arrays, I've written this function that works recursively as well. (See: https://gist.github.com/Nickology/f700e319cbafab5eaedc)
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));
Will result in:
Array
(
[A] => tom
[sum] => 30
[C] => Array
(
[0] => x
[1] => y
[z] => 145
[w] => 1
)
)
Here's the code:
<?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.
*
* 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;
}
?>
Here you have how I usually do this kind of operations.
// We declare an empty array in wich we will store the results
$sumArray = array();
// We loop through all the key-value pairs in $myArray
foreach ($myArray as $k=>$subArray) {
// Each value is an array, we loop through it
foreach ($subArray as $id=>$value) {
// If $sumArray has not $id as key we initialize it to zero
if(!isset($sumArray[$id])){
$sumArray[$id] = 0;
}
// If the array already has a key named $id, we increment its value
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
You can try this:
$c = array_map(function () {
return array_sum(func_get_args());
},$a, $b);
and finally:
print_r($c);
this works great on my laravel project
print_r($Array); // your original array
$_SUM = [];
// count($Array[0]) => if the number of keys are equall in all arrays then do a count of index 0 etc.
for ($i=0; $i < count($Array[0]); $i++) {
$_SUM[] = $Array[0][$i] + $Array[1][$i]; // do a for loop on the count
}
print_r($_SUM); // get a sumed up array
$sumArray = array();
foreach ($myArray as $k => $subArray) {
foreach ($subArray as $id => $value) {
if (!isset($sumArray[$id])) {
$sumArray[$id] = 0;
}
$sumArray[$id]+=$value;
}
}
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
if(!isset($sumArray[$id])){
$sumArray[$id] =$value;
}else {
$sumArray[$id]+=$value;
}
}
}
print_r($sumArray);
`
For example, you can pluck all fields from a result like this below.
I am picking out the 'balance' from an array and save to a variable
$kii = $user->pluck('balance');
then on the next line u can sum like this:
$sum = $kii->sum();
Hope it helps.
Code here:
$temp_arr = [];
foreach ($a as $k => $v) {
if(!is_null($v)) {
$sum = isset($temp_arr[$v[0]]) ? ((int)$v[5] + $sum) : (int)$v[5];
$temp_arr[$v[0]] = $sum;
}
}
return $temp_arr;
Result:
{SEQ_OK: 1328,SEQ_ERROR: 561}