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?
CodePudding user response:
Try the following:
$newCollection = collect([]);
$collectctions = 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
]
]);
foreach ($collectctions as $item) {
if($newCollection->contains('name', $item['name'])){
$index = $newCollection->where('name', $item['name'])->keys()[0];
$newCollection = $newCollection->map(function ($object, $i) use ($index, $item) {
if($i == $index){
$object['value'] = $item['value'];
}
return $object;
});
}
else{
$newCollection->push($item);
}
}
return $newCollection;
CodePudding user response:
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
)
)