You may use array_reduce
buil-in function to do the job. Also, when looping through the object's array (the callback), you should check if the result array has the current item's ID to verify that wether you need to add the item to the result array or to make the sum of points attributes.
Here's an example:
// a dummy class just to replicate the objects with ID and points attributes
class Dummy
{
public $id;
public $points;
public function __construct($id, $points)
{
$this->id = $id;
$this->points = $points;
}
}
// the array of objects
$arr = [new Dummy('xx', 25), new Dummy('xx', 40), new Dummy('xy', 40)];
// loop through the array
$res = array_reduce($arr, function($carry, $item) {
// holds the index of the object that has the same ID on the resulting array, if it stays NULL means it should add $item to the result array, otherwise calculate the sum of points attributes
$idx = null;
// trying to find the object that has the same id as the current item
foreach($carry as $k => $v)
if($v->id == $item->id) {
$idx = $k;
break;
}
// if nothing found, add $item to the result array, otherwise sum the points attributes
$idx === null ? $carry[] = $item:$carry[$idx]->points += $item->points;
// return the result array for the next iteration
return $carry;
}, []);
This will result in something like this:
array(2) {
[0]=>
object(Dummy)#1 (2) {
["id"]=>
string(2) "xx"
["points"]=>
int(65)
}
[1]=>
object(Dummy)#3 (2) {
["id"]=>
string(2) "xy"
["points"]=>
int(40)
}
}
Hope that helps, feel free to ask for further help.