2

Im not sure what function to search for in regards to this so cant seem to help myself. Seems like an obvious problem really. I have an array, and where I have duplicate keys, I wish to add the values. e.g:

This is a section of my array.

[1] => Array
    (
        [inputAvg] => 21.41 KB
        [outputAvg] => 22.03 KB
        [date] => 2011-08-01
    )

[2] => Array
    (
        [inputAvg] => 182.63 KB
        [outputAvg] => 186.05 KB
        [date] => 2011-08-01
    )

[3] => Array
    (
        [inputAvg] => 182.63 KB
        [outputAvg] => 186.05 KB
        [date] => 2011-08-02
    )

[4] => Array
    (
        [inputAvg] => 4.84 MB
        [outputAvg] => 4.93 MB
        [date] => 2011-08-03
    )

All I wish to do is, say where the date key of the array is the same (e.g. here 2011-08-01) I want to show this date once, but with combined values of the duplicate item....?

e.g

[1] => Array
    (
        [inputAvg] => 204.04 KB
        [outputAvg] => 208.08 KB
        [date] => 2011-08-01
    )


[2] => Array
    (
        [inputAvg] => 182.63 KB
        [outputAvg] => 186.05 KB
        [date] => 2011-08-02
    )

[3] => Array
    (
        [inputAvg] => 4.84 MB
        [outputAvg] => 4.93 MB
        [date] => 2011-08-03
    )
7
  • 2
    Combained?? added or concatenated ?? Commented Feb 19, 2013 at 12:49
  • sorry. added. ignore the MB KB, but sum of the two values...? Commented Feb 19, 2013 at 12:51
  • Please check stackoverflow.com/questions/2649500/… Commented Feb 19, 2013 at 12:52
  • 1
    Best solution for you could be checking for duplicates right when you add element to array. If the key already exists, it will add the values, if not it will add new key to array. Commented Feb 19, 2013 at 12:53
  • 1
    Use php.net/manual/en/control-structures.foreach.php Commented Feb 19, 2013 at 12:55

4 Answers 4

14
<?php

$array  = array(Array("inputAvg" => 21.41,"outputAvg" => 22.03,"date" => "2011-08-01"),
                Array("inputAvg" => 182.63,"outputAvg" => 186.05,"date" => "2011-08-01" ),
                Array("inputAvg" => 182.63, "outputAvg" => 186.05,"date" => "2011-08-02")
                );

$res  = array();
foreach($array as $vals){
    if(array_key_exists($vals['date'],$res)){
        $res[$vals['date']]['inputAvg']    += $vals['inputAvg'];
        $res[$vals['date']]['outputAvg']   += $vals['outputAvg'];
        $res[$vals['date']]['date']        = $vals['date'];
    }
    else{
        $res[$vals['date']]  = $vals;
    }
}

echo "<pre>";
print_r($res);

?>

Output :

Array
(
    [2011-08-01] => Array
        (
            [inputAvg] => 204.04
            [outputAvg] => 208.08
            [date] => 2011-08-01
        )

    [2011-08-02] => Array
        (
            [inputAvg] => 182.63
            [outputAvg] => 186.05
            [date] => 2011-08-02
        )

)
Sign up to request clarification or add additional context in comments.

2 Comments

+1 Superb bro..Saw two questions where you figured out great logic today..Amaging..Had tp praise u..I too got to solutions but not as quick as u!! IIt(ian)?
@SankalpMishra : Thanks buddy...but not iit (ian) because not tried ;)
1

Suppose, $data has all data that you want to process on

$dateArray = array();
foreach($data as $key => $value){
    if(in_array($value['date'], $dateArray)){
        $newArray[$value['date']]['inputAvg'] = $value['inputAvg'] + $newArray[$value['date']]['inputAvg'];
        $newArray[$value['date']]['outputAvg'] = $value['outputAvg'] + $newArray[$value['date']]['outputAvg'];
    }
    else{
        $dateArray[] = $value['date'];
        $newArray[$value['date']] = $value;
    }
}

But remember, that addition will just add your averages and not show KB/MB in the end. You will have to manipulate it.

Comments

0

Try this one ;

$new = array() ;

foreach ($stats as $traffic){
  $key = $traffic['date'] ;

  if (isset($new[$key])){
    if ($new[$key]['date'] === $traffic['date']){
      $new[$key]['inputAvg'] += $traffic['inputAvg'] ;
      $new[$key]['outputAvg'] += $traffic['outputAvg'] ;
    }
  } else {
    $new[$key] = $traffic ;
  }
}

var_dump($new) ;

Edited TYPO, so it works now.

Comments

0

Here is a solution that takes into account KB, MB and GB

Function to get absolute value from KB, MB and GB

function mul($unit) {
  $mul = 1;
  switch($unit) {
    case 'GB': $mul *= 1000;
    case 'MB': $mul *= 1000;
    case 'KB': $mul *= 1000;
  }
  return $mul;
}

Function to make a string from number, divided by G, M or K and add postfix

function demul($val) {
  $units = array('GB','MB','KB');
  $unit = '  ';
  $m = 1000000000;
  for ($i=0 ; $i<3 ; $i++) {
    if ($val >= $m) {
      $val /= $m;
      $unit = $units[$i];
      break;
    }
    $m /= 1000;
  }
  return number_format($val, 2) . ' ' . $unit;
}

Main loop, $arr is the original array ; fill dates array with summed data

$dates = array();
foreach ($arr as $key => $a) {
  $d = $a['date'];
  $i = explode(' ', $a['inputAvg']);
  $o = explode(' ', $a['outputAvg']);
  $in  = $i[0] * mul($i[1]);
  $out = $o[0] * mul($o[1]);

  if ( ! isset($dates[$d])) {
    $dates[$d] = array($in, $out);
  }
  else {
    $dates[$d][0] += $in;
    $dates[$d][1] += $out;
  }
}

Make result array based on original format

$result = array();
$n = 1;
foreach ($dates as $d => $a) {
  $result[$n++] = array('date' => $d, 'inputAvg' => demul($a[0]), 'outputAvg' => demul($a[1]));
}

Print result

print_r($result);

Given the data

$arr = array(
'1' => Array
    (
        'inputAvg' => '21.41 KB',
        'outputAvg' => '22.03 KB',
        'date' => '2011-08-01',
    ),

'2' => Array
    (
        'inputAvg' => '182.63 KB',
        'outputAvg' => '186.05 KB',
        'date' => '2011-08-01',
    ),

'3' => Array
    (
        'inputAvg' => '182.63 KB',
        'outputAvg' => '186.05 KB',
        'date' => '2011-08-02',
    ),

'4' => Array
    (
        'inputAvg' => '4.84 MB',
        'outputAvg' => '4.93 MB',
        'date' => '2011-08-03',
    )
);

It gives the output

Array
(
    [1] => Array
        (
            [date] => 2011-08-01
            [inputAvg] => 204.04 KB
            [outputAvg] => 208.08 KB
        )

    [2] => Array
        (
            [date] => 2011-08-02
            [inputAvg] => 182.63 KB
            [outputAvg] => 186.05 KB
        )

    [3] => Array
        (
            [date] => 2011-08-03
            [inputAvg] => 4.84 MB
            [outputAvg] => 4.93 MB
        )

)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.