user3352316
user3352316

Reputation: 167

PHP - Sum array at different levels

have an array laid out like so:

Array
(
0 =>
   array (
      'Country' => 'USA'
      'State' => 'California'
      'City' => 'Los Angeles'
      'qty'    => '200'
   )
1 =>
   array (
      'Country' => 'USA'
      'State' => 'California'
      'City' => 'San Diego'
      'qty'  => '50'
   )
2=>
  array (
      'Country' => 'USA'
      'State' => 'New York'
      'City' => 'Albany'
      'qty' => '100'
  )
)

I am trying to output the data with by each grouping with the total above:

USA                  350
   California        250
      Los Angeles    200
      San Diego       50
   New York          100
      Albany         100

I have used the approach here thus far: how to group result in subgroups in php

I would like to have the parent totals above the children and add more levels. I have the levels by repeating the loops, but how do I get the totals to display on the same row (above the children)before I get down to the last child?

Upvotes: 1

Views: 85

Answers (1)

ziollek
ziollek

Reputation: 1993

You can use array_reduce function to aggregate flat array, ie:

$data = array(
0 =>
   array (
      'Country' => 'USA',
      'State' => 'California',
      'City' => 'Los Angeles',
      'qty'    => '200'
   ),
1 =>
   array (
      'Country' => 'USA',
      'State' => 'California',
      'City' => 'San Diego',
      'qty'  => '50'
   ),
2=>
  array (
      'Country' => 'USA',
      'State' => 'New York',
      'City' => 'Albany',
      'qty' => '100'
  )
);

$result = array();

$result = array_reduce(
  $data,
  function($result, $element) {
    $prefix = '';
    foreach (array('Country', 'State', 'City') as $key) {
      if (!isset($result[$element[$key]])) {
        $result[$prefix.$element[$key]] = $element['qty'];
      } else {
        $result[$prefix.$element[$key]] += $element['qty'];
      }
      $prefix .= '  ';
    }
    return $result;
  },
  $result
);


print_r($result);

and the result is:

Array
(
    [USA] => 350
    [  California] => 50
    [    Los Angeles] => 200
    [    San Diego] => 50
    [  New York] => 100
    [    Albany] => 100
)

Upvotes: 1

Related Questions