TanGio
TanGio

Reputation: 766

Calculate the sum of elements if have the same date

I have a question, I have this array :

Array
(
[0] => Array
    (
        [date] => 2015-07-07
        [nb] => 12
    )

[1] => Array
    (
        [date] => 2015-07-10
        [nb] => 6
    )

[2] => Array
    (
        [date] => 2015-07-07
        [nb] => 8
    )

[3] => Array
    (
        [date] => 2015-07-09
        [nb] => 48
    )

[4] => Array
    (
        [date] => 2015-07-09
        [nb] => 42
    )
 }

But I want to obtain this:

Array
(
 [0] => Array
  (
    [date] => 2015-07-07
    [nb] => 20
  )

 [1] => Array
  (
    [date] => 2015-07-09
    [nb] => 90
   )

 [2] => Array
  (
    [date] => 2015-07-10
    [nb] => 6
   )
 }

The idea is if in the array exist multiple dates [nb] must be added up.

I tried like this:

foreach($aTotalRows as $k=>$row){
  if($row[$k]['date'] == $row[$k+1]['date']){
    $row[$k]['nb'] = $row[$k]['nb'] + $row[$k+1]['nb'] 
  }
}

But not work this solution, Can you help me please? Thx in advance

Upvotes: 2

Views: 1870

Answers (3)

splash58
splash58

Reputation: 26153

You can do it in one path

$keys = array(); // array date => index in result
$i = 0;
foreach($input as $item) 
   if (isset($keys[$item['date']]))                         // if exist
       $result[$keys[$item['date']]]['nb'] += $item['nb'];  //  add value
   else {  
       $keys[$item['date']] = $i;                           // create new items in arrays
       $result[$i++] = $item;
   }

print_r($result);

Upvotes: 2

viral
viral

Reputation: 3743

If you want to process unsorted array, you have to change your code something like,

$input = array(
    array('date' => '2015-07-07', 'nb' => 12),
    array('date' => '2015-07-10', 'nb' => 6),
    array('date' => '2015-07-07', 'nb' => 8),
    array('date' => '2015-07-09', 'nb' => 48),
    array('date' => '2015-07-09', 'nb' => 42)
 );

$required = array();

array_walk($input, function($v) use(&$required){
    if(!isset($required[$v['date']])){ $required[$v['date']] = 0; }
    $required[$v['date']] += $v['nb'];
});

$final = array_map(function($v, $k){
            return array('date'=>$k, 'nb'=>$v);
        }, $required, array_keys($required));

dump of $required

array (size=3)
  '2015-07-07' => int 20
  '2015-07-10' => int 6
  '2015-07-09' => int 90

dump of $final

array (size=3)
  0 => 
    array (size=2)
      'date' => string '2015-07-07' (length=10)
      'nb' => int 20
  1 => 
    array (size=2)
      'date' => string '2015-07-10' (length=10)
      'nb' => int 6
  2 => 
    array (size=2)
      'date' => string '2015-07-09' (length=10)
      'nb' => int 90

Upvotes: 2

Mark Baker
Mark Baker

Reputation: 212422

No, that will only work if you sort by date first.... try building something like:

$aggregateArray = array();
foreach($aTotalRows as $row) {
    if(!array_key_exists($row['date'], $aggregateArray) {
        $aggregateArray[$row['date']] = 0;
    }
    $aggregateArray[$row['date']] += $row['nb'] 
}

which will give you something like:

Array(
    ['2015-07-07'] => 20
    ['2015-07-10'] => 90
    ['2015-07-11'] => 6
)

and you can then restructure it if necessary

Upvotes: 8

Related Questions