I have $row which outputs the below. Array 0 – 4 do not change per user but the last items in each array need to be added together.
array ( 0 => '2', 1 => 'Joe', 2 => 'Bloggs', 3 => 'joe.bloggs@mail.com', 4 => '1,2', 5 => 1, 6 => 0, 7 => 1, )array ( 0 => '2', 1 => 'Joe', 2 => 'Bloggs', 3 => 'joe.bloggs@mail.com', 4 => '1,2', 5 => 0, 6 => 1, 7 => 1, )array ( 0 => '1', 1 => 'Jane', 2 => 'Doe', 3 => 'jane.doe@mail.com', 4 => '1,4', 5 => 1, 6 => 0, 7 => 1, )array ( 0 => '1', 1 => 'Jane', 2 => 'Doe', 3 => 'jane.doe@mail.com', 4 => '1,4', 5 => 0, 6 => 0, 7 => 0, )
I need to combine them so they are like this:
Array ( [0] => 2 [1] => Joe [2] => Bloggs [3] => joe.bloggs@mail.com [4] => 1,2 [5] => 1 [6] => 1 [7] => 2 ) Array ( [0] => 1 [1] => Jane [2] => Doe [3] => jane.doe@mail.com [4] => 1,4 [5] => 1 [6] => 0 [7] => 1 )
My code so far is:
$combined = array(); foreach ($row as $item) { if (!array_key_exists($item[0], $combined)) { $combined[$item[0]] = $item; } else { array_push($combined, $item); } }
But this is not doing what I expect. Not really sure where to go with this so any help would be much appreciated.
Thanks
Advertisement
Answer
You were very close. You simply needed to add the values.
/** * @param array $combined the combined array * @param array $item a single row of data (8-element array) * * @returns array the updated combined array */ function combineArray(array $combined, array $item) { // This is how we know whether the element exists or not $key = $item[0]; if (!array_key_exists($key, $combined)) { // This is a NEW item, so just add it to the combined array. $combined[$key] = $item; } else { // This already exists. Modify the required columns. $combined[$key][5] += $item[5]; $combined[$key][6] += $item[6]; $combined[$key][7] += $item[7]; /* You could also do this automatically from the type of variable, instead of specifying 5, 6 and 7: foreach ($item as $i => $value) { if (in_array(gettype($value), array('integer', 'float'))) { $combined[$key][$i] += $value; } } */ } return $combined; } $combined = array(); foreach ($row as $item) { $combined = combineArray($combined, $item); } // Now convert to "true" array. This is VERY IMPORTANT if you want to output // it to, say, JSON, where [ 0 => 'a', 1 => 'b' ] and [ 0 => 'a', 2 => 'b' ] // are two different KINDS of object (the first an array, the second a dict) $combined = array_values($combined);
or also (to show the call with a single row):
$item = array ( 0 => '2', 1 => 'Joe', 2 => 'Bloggs', 3 => 'joe.bloggs@mail.com', 4 => '1,2', 5 => 1, 6 => 0, 7 => 1, ); $combined = combineArray($combined, $item);
The loop version works as expected with the following data:
$row = array( array ( 0 => '2', 1 => 'Joe', 2 => 'Bloggs', 3 => 'joe.bloggs@mail.com', 4 => '1,2', 5 => 1, 6 => 0, 7 => 1, ),array ( 0 => '2', 1 => 'Joe', 2 => 'Bloggs', 3 => 'joe.bloggs@mail.com', 4 => '1,2', 5 => 0, 6 => 1, 7 => 1, ),array ( 0 => '1', 1 => 'Jane', 2 => 'Doe', 3 => 'jane.doe@mail.com', 4 => '1,4', 5 => 1, 6 => 0, 7 => 1, ),array ( 0 => '1', 1 => 'Jane', 2 => 'Doe', 3 => 'jane.doe@mail.com', 4 => '1,4', 5 => 0, 6 => 0, 7 => 0, ));
and outputs:
Array ( [0] => Array ( [0] => 2 [1] => Joe [2] => Bloggs [3] => joe.bloggs@mail.com [4] => 1,2 [5] => 1 [6] => 1 [7] => 2 ) [1] => Array ( [0] => 1 [1] => Jane [2] => Doe [3] => jane.doe@mail.com [4] => 1,4 [5] => 1 [6] => 0 [7] => 1 ) )