Matt Toner Matt Toner - 1 month ago 6
PHP Question

PHP Arrays - Merge two arrays where a value is added together

I need some more help regarding PHP Arrays and the issue I am having. I have an array like this: -

array(2) {
[0]=>
array(2) {
[0]=>
array(2) {
["count"]=>
string(3) "100"
["id"]=>
int(46)
}
[1]=>
array(2) {
["count"]=>
string(3) "300"
["id"]=>
int(53)
}
}
[1]=>
array(1) {
[0]=>
array(2) {
["count"]=>
string(3) "200"
["id"]=>
int(46)
}
}
}


However, I would like it to look more like this as array: -

array(2) {
[0]=>
array(2) {
["count"]=>
string(3) "300" <--- This has been added from Array 1 and 2
["id"]=>
int(46)
}
[1]=>
array(2) {
["count"]=>
string(3) "300"
["id"]=>
int(53)
}
}


Basically if the same id is in both areas I want the count number to be added to each other but if it's not then it needs to just be left alone and included in the array.

I have used a number of array functions such as array_merge and array_push but I am running out of ideas of how this could work. I have also started working on a foreach with if statements but I just got myself completely confused. I just need a second pair of eyes to look at the issue and see howe it can be done.

Thanks again everyone.

Answer

Should work with something like this:

$idToCountArray = array(); //temporary array to store id => countSum
array_walk_recursive($inputArray, function($value,$key) { //walk each array in data structure
    if(isset(value['id']) && isset($value['count'])) {
        //we have found an entry with id and count:
        if(!isset($idToCountArray[$value['id']])) {
            //first count for id => create initial count
            $idToCountArray[$value['id']] = intval($value['count']);
        } else {
            //n'th count for id => add count to sum
            $idToCountArray[$value['id']] += intval($value['count']);
        }
    }
});
//build final structure:
$result = array();
foreach($idToCountArray as $id => $countSum) {
    $result[] = array('id' => $id, 'count' => ''.$countSum);
}

Please note that I have not testet the code and there is probably a more elegant/performant solution.