Reputation: 259
I need to sum the column data of rows after grouping by another column.
Example input:
[
['id' => 1, 'name' => 'John00', 'value' => 0.4],
['id' => 2, 'name' => 'Ann01', 'value' => 0.001],
['id' => 1, 'name' => 'John00', 'value' => 0.2],
['id' => 3, 'name' => 'Ann', 'value' => 0.1],
['id' => 2, 'name' => 'Ann01', 'value' => 0.01],
['id' => 1, 'name' => 'John00', 'value' => 0.3],
]
How can I consolidate rows with the same id
and sum the value
values in each group to return an indexed array of associative arrays?
Desired result:
Array
(
[0] => Array
(
[id] => 1
[name] => John00
[value] => 0.9
)
[1] => Array
(
[id] => 2
[name] => Ann01
[value] => 0.011
)
[2] => Array
(
[id] => 3
[name] => Ann
[value] => 0.1
)
)
Upvotes: -1
Views: 972
Reputation: 57815
I'm not completely sure what you are trying to do - I assume you want the sum grouped by the id for each distinct id to populate a flat associative array, but I may be wrong.
$sums = array();
foreach ($source as $ar) {
//create an entry for this id in the array of sums if does not exist.
if (!isset($sums[ $ar['id'] ])) {
$sums[ $ar['id'] ] = 0;
}
//add 'value' key to sum for that id
$sums[ $ar['id'] ] += $ar['value'];
}
//sort by id
ksort($sums);
print_r($sums);
Output:
Array
(
[1] => 0.9
[2] => 0.011
[3] => 0.1
)
Upvotes: 2
Reputation: 75704
This looks like it's coming from a database, and the query is the best place to do such things. (if this is not data from a db, just ignore this answer).
SELECT id, MAX(name), SUM(value)
FROM YourTable
-- add your WHERE-constraints here
GROUP BY id;
Upvotes: 0
Reputation: 47894
To ensure that the result array has the same structure of the input array (an indexed array of associative rows) -- just reducing the total row count in the process -- push the whole as a reference variable into the result array whenever a unique id
value is encountered. If a row is encountered where the id
has been encountered before, only add the current value
value to the value
value in the reference.
Code: (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row['id']])) {
$ref[$row['id']] = $row;
$result[] =& $ref[$row['id']];
continue;
}
$ref[$row['id']]['value'] += $row['value'];
}
print_r($result);
Upvotes: 0
Reputation: 19225
Pseduo-code:
$totals = array();
function add($in)
{
global $totals;
if(!isset($totals($in['id']))
{
$totals[$in['id']] = $in['value'];
}else
{
$totals[$in['id']] += $in['value'];
}
}
array_walk('add',$input_array);
var_dump($totals);
Upvotes: -1