I’m working on Lumen and my collection has duplicate values, example:
collect([ [ 'name' => 'John Doe', 'department' => 'Sales', 'phone' => '99999-99999', 'value' => 25.0 ], [ 'name' => 'Mary Lisa', 'department' => 'Finance', 'phone' => '88888-88888', 'value' => 5.0 ], [ 'name' => 'Mary Lisa', 'department' => 'Finance', 'phone' => '88888-88888', 'value' => 58.0 ], [ 'name' => 'Lucas Rodrigues', 'department' => 'Marketing', 'phone' => '22222-22222', 'value' => 90.0 ] ])
I would like to sum the value property when the name is the same but preserve other values like (department and phone) and remove duplicates entity, example:
collect([ [ 'name' => 'John Doe', 'department' => 'Sales', 'phone' => '99999-99999', 'value' => 25.0 ], [ 'name' => 'Mary Lisa', 'department' => 'Finance', 'phone' => '88888-88888', 'value' => 63.0 ], [ 'name' => 'Lucas Rodrigues', 'department' => 'Marketing', 'phone' => '22222-22222', 'value' => 90.0 ] ])
What’s the best way to do this?
Advertisement
Answer
This can be achieved using collection functions (https://laravel.com/docs/8.x/collections). In this example I solved it using (groupBy
, map
, flatten
, slice
, count
and sum
).
$data = collect([ [ 'name' => 'John Doe', 'department' => 'Sales', 'phone' => '99999-99999', 'value' => 25.0 ], [ 'name' => 'Mary Lisa', 'department' => 'Finance', 'phone' => '88888-88888', 'value' => 5.0 ], [ 'name' => 'Mary Lisa', 'department' => 'Finance', 'phone' => '88888-88888', 'value' => 58.0 ], [ 'name' => 'Lucas Rodrigues', 'department' => 'Marketing', 'phone' => '22222-22222', 'value' => 90.0 ] ]); $data = $data->groupBy('name')->map(function ($item) { if ($item->count() > 1) { $item = $item->slice(0, 1)->map(function($subItem) use ($item) { $subItem['value'] = $item->sum('value'); return $subItem; }); } return $item; }) ->flatten(1);
When calling print_r($data->toArray());
we get the following array as result:
Array ( [0] => Array ( [name] => John Doe [department] => Sales [phone] => 99999-99999 [value] => 25 ) [1] => Array ( [name] => Mary Lisa [department] => Finance [phone] => 88888-88888 [value] => 63 ) [2] => Array ( [name] => Lucas Rodrigues [department] => Marketing [phone] => 22222-22222 [value] => 90 ) )