Skip to content
Advertisement

Laravel Lumen Collection – Group By With Sum and preserve the values

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
        )

)
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement