This question already has an answer here:
I need help regarding foreach
and arrays in PHP
Say I have the following array:
$orders = array (
0 =>
array (
'company' => 'Company 1',
'total' => '5',
),
1 =>
array (
'company' => 'Company 2',
'total' => '10',
),
2 =>
array (
'company' => 'Company 1',
'total' => '15',
),
3 =>
array (
'company' => 'Company 1',
'total' => '5',
),
4 =>
array (
'company' => 'Company 3',
'total' => '12',
)
);
Order 1 is 5 for Company 1
Order 2 is 10 for Company 2
Order 3 is 15 for Company 1
Order 4 is 5 for Company 2
Order 5 is 12 for Company 3
I want the output to show the company name and the accumulative total of each company's orders
For example:
Company 1 20
Company 2 15
Company 3 12
</div>
Just create another array that will track the orders.
$companies = array();
foreach ($orders as $order) {
if (array_key_exists($order["company"], $companies)) {
$companies[$order["company"]] += $order["total"];
} else {
$companies[$order["company"]] = $order["total"];
}
}
First, we check if the company is already in the companies array, if it is then we add the total to that company's current total.
Otherwise, we just create a new key and store the total.
Additionally, you can write (int)$order["total"]
to typecast into integer.
This might be useful to ensure that you have the correct data.
One way to do this with a foreach loop where you increment some variable :
// Your array
$array = array(...);
// Init of the sum of each total for each company
$c1 = 0;
$c2 = 0;
$c3 = 0;
// You loop through your array and test the output
foreach ($array as $order => $value_array) {
switch($value_array['company']) {
case 'Company 1' : $c1 += intval($value_array['total']); break;
case 'Company 2' : $c2 += intval($value_array['total']); break;
case 'Company 3' : $c3 += intval($value_array['total']); break;
}
}
//$c1 will be the sum for company 1;
//$c2 for the company 2;
//$c3 for the company 3.
Is it what you are looking for?
array_reduce()
solution:
$groups = array_reduce($orders, function($r, $a) {
$k = $a['company'];
(isset($r[$k]))? $r[$k] += $a['total'] : $r[$k] = $a['total'];
return $r;
}, []);
foreach ($groups as $k => $v) {
printf("%-20s%d
", $k, $v);
}
The output:
Company 1 25
Company 2 10
Company 3 12
Just another way: array_walk
$result = array();
array_walk($orders, function ($element) use (&$result) {
$company = $element['company'];
if (!isset($result[$company]))
$result[$company] = 0;
$result[$company] += $element['total'];
});
For this input:
$orders = array(
0 =>
array(
'company' => 'Company 1',
'total' => '5',
),
1 =>
array(
'company' => 'Company 2',
'total' => '10',
),
2 =>
array(
'company' => 'Company 1',
'total' => '15',
),
3 =>
array(
'company' => 'Company 1',
'total' => '5',
),
4 =>
array(
'company' => 'Company 3',
'total' => '12',
)
);
The output will be:
array(3) {
["Company 1"]=>
int(25)
["Company 2"]=>
int(10)
["Company 3"]=>
int(12)
}