I have a multidimensional array in the following format :
array (
0 =>
array (
'manual' => 1,
'cancelled' => 1,
'expired' => 1,
'earned' => 1,
'user' =>
array (
'user1' => 1,
'user2' => 1,
'user3' => 1,
'user4' => 1,
),
'transfer' =>
array (
'transfer1' =>
array (
'key1' => 1,
'key2' => 1,
'key3' => 1,
),
'transfer2' =>
array (
'key5' => 1,
'key6' => 1,
'key7' => 1,
),
),
'date' => '2018-03-07',
),
1 =>
array (
'manual' => 1,
'cancelled' => 1,
'expired' => 1,
'earned' => 1,
'user' =>
array (
'user1' => 1,
'user2' => 1,
'user3' => 1,
'user4' => 1,
),
'transfer' =>
array (
'transfer1' =>
array (
'key1' => 1,
'key2' => 1,
'key3' => 1,
),
'transfer2' =>
array (
'key5' => 1,
'key6' => 1,
'key7' => 1,
),
),
'date' => '2018-03-08',
),
)I need to calculate the sum of the array values with same index. So the total array should be as the following
Array
(
[total] => Array
(
[manual] => 2
[cancelled] => 2
[expired] => 2
[earned] => 2
[user] => Array
(
[user1] => 2
[user2] => 2
[user3] => 2
[user4] => 2
)
[transfer] => Array
(
[transfer1] => Array
(
[key1] => 2
[key2] => 2
[key3] => 2
)
[transfer2] => Array
(
[key5] => 2
[key6] => 2
[key7] => 2
)
)
That is the total should have the same format except date, but it needs to show the total sum of the value. How can this be done in PHP ? I have used the following code
$final = array_shift($input);
foreach ($final as $key => &$value){
$value += array_sum(array_column($input, $key));
}
unset($value);
var_dump($final);
where $input is considered as the first array and $final is total. I think this only work with single indexes.
You can use recursive function which walk through all you "tree".
There
If element is array create same in result array and run function for each key. If it has a number, just add value to result.
Here is a SAMPLE
<?php
// Array with data
$arr=array(array('manual'=>1,'cancelled'=>1,'expired'=>1,'earned'=>1,'user'=>array('user1'=>1,'user2'=>1,'user3'=>1,'user4'=>1,),'transfer'=>array('transfer1'=>array('key1'=>1,'key2'=>1,'key3'=>1,),'transfer2'=>array('key5'=>1,'key6'=>1,'key7'=>1,)),'date'=>'2018-03-07',),array('manual'=>1,'cancelled'=>1,'expired'=>1,'earned'=>1,'user'=>array('user1'=>1,'user2'=>1,'user3'=>1,'user4'=>1,),'transfer'=>array('transfer1'=>array('key1'=>2,'key2'=>2,'key3'=>2,),'transfer2'=>array('key5'=>2,'key6'=>2,'key7'=>2,)),'date'=>'2018-03-08',));
//Init result array
$res=array('total'=>array());
foreach ($arr as $key=>$val) {
//Run it for each element and store result to $res['total']
countTotal($res['total'],$val);
}
//Show result
print_r($res);
/*
* Count totals for branch of array
* @param $res - reference to branch of result array
* @param $arr - branch of data array
*/
function countTotal(&$res,$arr) {
foreach ($arr as $key=>$val) {
if (is_array($val)) {
//it's array. Create "branch" in $res and run countTotal() to calc total for it
if (!isset($res[$key])) $res[$key]=array();
countTotal($res[$key],$val);
} else if (is_numeric($val)) {
// it's number. Create "leaf" if need and add value.
if (!isset($res[$key])) $res[$key]=0;
$res[$key]+=$val;
}
}
}
As you see it use reference to branch of result array for accumulating totals
Results
Array
(
[total] => Array
(
[manual] => 2
[cancelled] => 2
[expired] => 2
[earned] => 2
[user] => Array
(
[user1] => 2
[user2] => 2
[user3] => 2
[user4] => 2
)
[transfer] => Array
(
[transfer1] => Array
(
[key1] => 3
[key2] => 3
[key3] => 3
)
[transfer2] => Array
(
[key5] => 3
[key6] => 3
[key7] => 3
)
)
)
)
In second "transfer" I have used "2" so it's "3" in sum
You can write the recursive function like the following:
function array_sum_recursive_assoc($array, &$result = [])
{
$keys = array_keys($array[0] ?? []);
foreach ($keys as $key) {
foreach (($column = array_column($array, $key)) as $value) {
if (is_array($value)) {
$result[$key] = [];
array_sum_recursive_assoc($column, $result[$key]);
continue 2;
}
// In this case date safe guard.
if (!is_numeric($value)) {
continue;
}
$result[$key] = ($result[$key] ?? 0) + $value;
}
}
return $result;
}
var_dump(array_sum_recursive_assoc($array));
Here is the demo.
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