Steve Goerger
Steve Goerger

Reputation: 51

PHP Multidimensional Array: Combine By Key And Add Values Of Another Key

have an array like this:

    array (
  '@attributes' => 
  array (
    'status' => 'ok',
  ),
  'time_entries' => 
  array (
    '@attributes' => 
    array (
      'page' => '1',
      'per_page' => '100',
      'pages' => '1',
      'total' => '33',
    ),
    'time_entry' => 
    array (
      0 => 
      array (
        'time_entry_id' => '1411884',
        'staff_id' => '22384',
        'project_id' => '11116',
        'task_id' => '3296',
        'hours' => '1.75',
        'date' => '2017-02-20',
        'notes' => 'What is Quadra, Events Slider, Event Page Setup',
        'billed' => '0',
      ),
      1 => 
      array (
        'time_entry_id' => '1411254',
        'staff_id' => '22384',
        'project_id' => '11116',
        'task_id' => '3296',
        'hours' => '1.5',
        'date' => '2017-02-17',
        'notes' => 'Events Slider, Background overlay, Intro',
        'billed' => '0',
      ),
      2 => 
      array (
        'time_entry_id' => '1410694',
        'staff_id' => '22384',
        'project_id' => '11116',
        'task_id' => '3296',
        'hours' => '2.75',
        'date' => '2017-02-16',
        'notes' => 'Background Image SVGs, Header, Footer',
        'billed' => '0',
      ),
      3 => 
      array (
        'time_entry_id' => '1410586',
        'staff_id' => '22384',
        'project_id' => '11116',
        'task_id' => '3296',
        'hours' => '0.5',
        'date' => '2017-02-15',
        'notes' => 'Site Background 
Assign Less Variables',
        'billed' => '0',
      ),
      4 => 
      array (
        'time_entry_id' => '1409621',
        'staff_id' => '22384',
        'project_id' => '11116',
        'task_id' => '3296',
        'hours' => '0.25',
        'date' => '2017-02-14',
        'notes' => 'Theme Install',
        'billed' => '0',
      ),

...it actually goes on further than those first 4. What I am looking to do is sort these arrays by the key ["task_id"] so that I can group those together, and then add together the ["hours"] key - so that at the end I can output the total number of hours worked on under each task_id.

I've tried a bit of 'array_merge_recursive'and similar but I'm at a loss; this is PHP a good bit above my level. Help very appreciated.

Upvotes: 1

Views: 74

Answers (2)

Rockholla
Rockholla

Reputation: 61

So you're probably just better off doing a group by and summation by generating a new set of data rather than trying to modify this array.

Something like this will give you what you're looking for:

$time_entries = $your_array["time_entries"]["time_entry"];
$task_hours = [];
foreach ($time_entries as $time_entry) {
    if (!isset($task_hours[$time_entry["task_id"]])) {
        $task_hours[$time_entry["task_id"]] = 0;
    }
    $task_hours[$time_entry["task_id"]] += (float) $time_entry["hours"];
}

$task_hours would give you a value like:

Array
(
    [3296] => 5
    [1879] => 0.25
)

Upvotes: 1

RiggsFolly
RiggsFolly

Reputation: 94642

Instead of sorting the array and then summing the hours why not process over the relevant part of that array and do the summation all in one go.

$tots = array();
foreach( $array['time_entry'] as $task ) {
    if ( isset($tots['task_id']) ) {
        $tots['task_id'] += $task['hours'];
    } else {
        $tots['task_id'] = $task['hours'];
    }
}

You should now have an array where the key is the task_id and its value is the summation of all that keys hours.

If you want the task_id's in order then sort the $tots array before outputing any results

ksort($tots);

If you want the results in order of the number of hours

asort($tots);

Upvotes: 0

Related Questions