PHP Arrays: Summary Values โ€‹โ€‹with Corresponding Dates

I am trying to figure out how to sum specific values โ€‹โ€‹of a multidimensional array if they have the same dates.

Here is my array:

<?$myArray=array( array( 'year' => 2011, 'month ' => 5, 'day' => 13, 'value' => 2 ), array( 'year' => 2011, 'month '=> 5, 'day' => 14, 'value' => 5 ), array( 'year' => 2011, 'month ' => 5, 'day' => 13, 'value' => 1 ), array( 'year' => 2011, 'month ' => 5, 'day' => 14, 'value' => 9 ) );?> 

this is how i want the result to look:

 <?$output=array( array( 'year' => 2011, 'month ' => 5, 'day' => 13, 'value' => 3 //the sum of 1+2 ), array( 'year' => 2011, 'month '=> 5, 'day' => 14, 'value' => 14 //the sum of 5+9 ) );?> 

Notice how the 4 sub-bands were mapped to year/month/day , and then only value summed. I saw other SO topics in this section , but I canโ€™t find one where only value summed, not year/month/day .

Thoughts?

+4
source share
2 answers

The easiest way is to index your output array first using the year / month / day combination:

Note The above array of examples has all of its month keys with finite space. I just use month here with no spaces.

 // Initialize output array... $out = array(); // Looping over each input array item foreach ($myArray as $elem) { // Initialize a new element in the output keyed as yyyy-mm-dd if it doesn't already exist if (!isset($out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']])) { $out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']] = array( // Set the date keys... 'year' => $elem['year'], 'month' => $elem['month '], 'day' => $elem['day'], // With the current value... 'value' => $elem['value'] ); } // If it already exists, just add the current value onto it... else { $out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']]['value'] += $elem['value']; } } // Now your output array is keyed by date. Use array_values() to strip off those keys if it matters: $out = array_values($out); 

Outputs (before calling array_values() ):

 array(2) { '2011-5-13' => array(4) { 'year' => int(2011) 'month' => int(5) 'day' => int(13) 'value' => int(3) } '2011-5-14' => array(4) { 'year' => int(2011) 'month' => int(5) 'day' => int(14) 'value' => int(14) } } 

Update:

To do the same with single-key dates (rather than 3 parts), it is easier without concatenation:

 $myArray=array( array( 'date' => '2011-05-13', 'value' => 2 ), array( 'date' => '2011-05-14', 'value' => 5 ), array( 'date' => '2011-05-13', 'value' => 7 ), array( 'date' => '2011-05-14', 'value' => 3 ), ); foreach ($myArray as $elem) { // Initialize a new element in the output if it doesn't already exist if (!isset($out[$elem['date']])) { $out[$elem['date'] = array( // Set the date keys... 'date' => $elem['date'], // With the current value... 'value' => $elem['value'] ); } else { $out[$elem['date']]['value'] += $elem['value']; } } 
+4
source

This is how I do it. The result will be in $newArray with datetime objects as keys. If you just want this to be an indexed array, this is pretty easy to do.

 // Example array $myArray = array( array( 'date' => new DateTime('1993-08-11'), 'value' => 3 ), array( 'date' => new DateTime('1993-08-11'), 'value' => 5 ) ); $newArray = array(); foreach($myArray as $element) { $iterationValue = $element['value']; $iterationDate = $element['date']; $dateKey = $iterationDate->format('Ym-d'); if(array_key_exists($dateKey, $newArray)) { // If we've already added this date to the new array, add the value $newArray[$dateKey]['value'] += $iterationValue; } else { // Otherwise create a new element with datetimeobject as key $newArray[$dateKey]['date'] = $iterationDate; $newArray[$dateKey]['value'] = $iterationValue; } } nl2br(print_r($newArray)); 

In fact, it all ended up the same as @MichaelBerkowski's solution. However, having DateTime objects is always more flexible unless you do something with dates later in your application.

Edit: now tested and fixed errors

+2
source

All Articles