2

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

4 Answers4

2

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.

JustCarty
  • 3,839
  • 5
  • 31
  • 51
  • This was the perfect solution! Thanks a lot. Worth noting that I then successfully used uasort to sort the array. –  Feb 21 '18 at 13:35
2

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\n", $k, $v);
}

The output:

Company 1           25
Company 2           10
Company 3           12
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
1

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?

Mickaël Leger
  • 3,426
  • 2
  • 17
  • 36
0

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)
}
Scaramouche
  • 3,188
  • 2
  • 20
  • 46