-3
[
    0 => [
        'qty' => 10
        'section' => 'VK7B'
        'time_window' => 1
    ]
    1 => [
        'qty' => 1
        'section' => 'STIC'
        'time_window' => 1
    ]
    2 => [
        'qty' => 1
        'section' => 'STIC'
        'time_window' => 1
    ]
]

I have this multidimensional array where I want to merge the array's if both the section and the time_window are the same, summing the qty for that array. What is an elegant way to do this?

I have tried this ($sections being the multidimensional arry), but this changes the keys and only checks for one value:

$new = []
foreach ($sections as $s) {
   if (isset($new[$s['section']])) {
        $new[$s['section']]['qty'] += $s['qty'];
        $new[$s['section']]['time_window'] = $s['time_window'];
    } else {
        $new[$s['section']] = $s;
    }
}
[
    'VK7B' => [
        'qty' => 10
        'section' => 'VK7B'
        'time_window' => 1
    ]
    'STIC' => [
        'qty' => 2
        'section' => 'STIC'
        'time_window' => 1
    ]
]
RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
Bowis
  • 541
  • 8
  • 31
  • 1
    Looks good, and elegant, and self documenting to me. Except you are not checking that the `time_window` are the same – RiggsFolly Apr 10 '21 at 08:57
  • @RiggsFolly yes, i'm not sure how I should add a second check for the time_window – Bowis Apr 10 '21 at 09:08

1 Answers1

2

As pointed by @RiggsFolly in the comment you are not checking time_window are the same.

You can do it with this code:

$new = []
foreach ($sections as $s) {
   // you need to save both values (section and time_window) to check both of them
   if (isset($new[$s['section'].$s['time_window']])) {
        $new[$s['section'].$s['time_window']]['qty'] += $s['qty'];
        $new[$s['section'].$s['time_window']]['time_window'] = $s['time_window'];
    } else {
        $new[$s['section'].$s['time_window']] = $s;
    }
}

// Now $new is an associative array => let's transform it in a normal array
$new = array_values($new);
Giacomo M
  • 4,450
  • 7
  • 28
  • 57