How to count distinct values from a collection in Laravel?

15,058

Solution 1

Update for 2021/L6+

thanks @JeremyWadhams

$degrees->groupBy('Degree')->map(fn ($people) => $people->count());
// or using HigherOrder proxy on the collection
$degrees->groupBy('Degree')->map->count();

Using collection methods this would be it:

$degrees->groupBy('Degree')->map(function ($people) {
    return $people->count();
});
// Collection {
//   'Master' => 13,
//   'Bachelor' => 9,
//   'PhD' => 3
// }

Solution 2

There is a Collection Helper called CountBy, does exactly what you need.

Collections CountBy

$degrees->countBy('Degree');

It will retourn as expected

 Array
(
    [Master] => 13
    [Bachelor] => 9
    [PhD] => 3
)

Simple :D

Share:
15,058

Related videos on Youtube

Pathros
Author by

Pathros

I like developing web apps with Laravel, including the deployment and security setting up. My interests: Favorite programming languages/frameworks/technologies/OS Laravel Homestead Php Javascript Docker Nginx Traefik Laradock Ubuntu MySQL Livewire Alpine.js Tailwind CSS Bootstrap Git wish list: Ansible Arduino Docker swarm Envoy Flutter Kubernetes Python Terraform Oracle APEX R Nvim Raspberry pi

Updated on September 15, 2022

Comments

  • Pathros
    Pathros about 1 month

    I have been struggling on how to get the quantity of distinct values from a collection in Eloquent.

    I have been trying several methods, such as unique(), values(), etc., found on the docs. Even though there is indeed a count() method, there is no method to get the count of distinct values.

    For example, by applying the following query

    $technicalshighestdegrees = Capsule::table('academicinfo AS fa')
            ->selectRaw('DISTINCT fa.academic_id AS Id,c.name AS Degree')
            ->leftJoin('academics AS a','fa.academic_id','=','a.id')
            ->leftJoin('cat_degree AS c','fa.level','=','c.id')
            ->whereIn('a.type',['Technical'])
            ->where('a.status','!=','Retired')
            ->where('c.degree',true)
            ->orderBy('a.id')
            ->orderBy('c.hierarchy','desc')/*http://stackoverflow.com/a/17006377/1883256*/
            ->get();
    

    I get this collection:

    Illuminate\Support\Collection Object
    (
        [items:protected] => Array
            (
                [0] => stdClass Object
                    (
                        [Id] => 3
                        [Grado] => Master
                    )
                [1] => stdClass Object
                    (
                        [Id] => 3
                        [Grado] => Bachelor
                    )
                [2] => stdClass Object
                    (
                        [Id] => 4
                        [Grado] => Master
                    )
                [3] => stdClass Object
                    (
                        [Id] => 4
                        [Grado] => Bachelor
                    )
                [4] => stdClass Object
                    (
                        [Id] => 6
                        [Grado] => Master
                    )
                [5] => stdClass Object
                    (
                        [Id] => 6
                        [Grado] => Bachelor
                    )
                [6] => stdClass Object
                    (
                        [Id] => 18
                        [Grado] => Bachelor
                    )
                [7] => stdClass Object
                    (
                        [Id] => 27
                        [Grado] => Bachelor
                    )
                [8] => stdClass Object
                    (
                        [Id] => 34
                        [Grado] => Master
                    )
                [9] => stdClass Object
                    (
                        [Id] => 34
                        [Grado] => Bachelor
                    )
                [10] => stdClass Object
                    (
                        [Id] => 36
                        [Grado] => PhD
                    )
                [11] => stdClass Object
                    (
                        [Id] => 36
                        [Grado] => Master
                    )
                [12] => stdClass Object
                    (
                        [Id] => 36
                        [Grado] => Bachelor
                    )
                [13] => stdClass Object
                    (
                        [Id] => 37
                        [Grado] => Bachelor
                    )
                [14] => stdClass Object
                    (
                        [Id] => 42
                        [Grado] => PhD
                    )
                [15] => stdClass Object
                    (
                        [Id] => 42
                        [Grado] => Master
                    )
                [16] => stdClass Object
                    (
                        [Id] => 42
                        [Grado] => Bachelor
                    )
                [17] => stdClass Object
                    (
                        [Id] => 50
                        [Grado] => Bachelor
                    )
                [18] => stdClass Object
                    (
                        [Id] => 52
                        [Grado] => Bachelor
                    )
                [19] => stdClass Object
                    (
                        [Id] => 53
                        [Grado] => Master
                    )
                [20] => stdClass Object
                    (
                        [Id] => 53
                        [Grado] => Bachelor
                    )
                [21] => stdClass Object
                    (
                        [Id] => 54
                        [Grado] => Master
                    )
                [22] => stdClass Object
                    (
                        [Id] => 54
                        [Grado] => Bachelor
                    )
                [23] => stdClass Object
                    (
                        [Id] => 55
                        [Grado] => Master
                    )
                [24] => stdClass Object
                    (
                        [Id] => 55
                        [Grado] => Bachelor
                    )
                [25] => stdClass Object
                    (
                        [Id] => 57
                        [Grado] => Bachelor
                    )
                [26] => stdClass Object
                    (
                        [Id] => 68
                        [Grado] => Master
                    )
                [27] => stdClass Object
                    (
                        [Id] => 68
                        [Grado] => Bachelor
                    )
                [28] => stdClass Object
                    (
                        [Id] => 72
                        [Grado] => Master
                    )
                [29] => stdClass Object
                    (
                        [Id] => 72
                        [Grado] => Bachelor
                    )
                [30] => stdClass Object
                    (
                        [Id] => 77
                        [Grado] => Bachelor
                    )
                [31] => stdClass Object
                    (
                        [Id] => 82
                        [Grado] => Bachelor
                    )
                [32] => stdClass Object
                    (
                        [Id] => 85
                        [Grado] => PhD
                    )
                [33] => stdClass Object
                    (
                        [Id] => 85
                        [Grado] => Master
                    )
                [34] => stdClass Object
                    (
                        [Id] => 85
                        [Grado] => Bachelor
                    )
                [35] => stdClass Object
                    (
                        [Id] => 92
                        [Grado] => Master
                    )
                [36] => stdClass Object
                    (
                        [Id] => 92
                        [Grado] => Bachelor
                    )
                [37] => stdClass Object
                    (
                        [Id] => 100
                        [Grado] => Master
                    )
                [38] => stdClass Object
                    (
                        [Id] => 100
                        [Grado] => Bachelor
                    )
                [39] => stdClass Object
                    (
                        [Id] => 111
                        [Grado] => Bachelor
                    )
                [40] => stdClass Object
                    (
                        [Id] => 117
                        [Grado] => Master
                    )
                [41] => stdClass Object
                    (
                        [Id] => 117
                        [Grado] => Bachelor
                    )
                [42] => stdClass Object
                    (
                        [Id] => 123
                        [Grado] => Master
                    )
                [43] => stdClass Object
                    (
                        [Id] => 123
                        [Grado] => Bachelor
                    )
            )
    )
    

    Since, I just want to get the highest degrees (a user Id may have several historical degrees), I apply the unique() method, that according to the docs, it leaves only the first original value, in my case, I have already ordered them by hierarchy desc:

    $technicalshighestdegrees = $technicalshighestdegrees->unique('Id');
    

    And now I get the following collection (reduced to 25 items, which is exactly the total number):

    Illuminate\Support\Collection Object
    (
        [items:protected] => Array
            (
                [0] => stdClass Object
                    (
                        [Id] => 3
                        [Degree] => Master
                    )
                [2] => stdClass Object
                    (
                        [Id] => 4
                        [Degree] => Master
                    )
                [4] => stdClass Object
                    (
                        [Id] => 6
                        [Degree] => Master
                    )
                [6] => stdClass Object
                    (
                        [Id] => 18
                        [Degree] => Bachelor
                    )
                [7] => stdClass Object
                    (
                        [Id] => 27
                        [Degree] => Bachelor
                    )
                [8] => stdClass Object
                    (
                        [Id] => 34
                        [Degree] => Master
                    )
                [10] => stdClass Object
                    (
                        [Id] => 36
                        [Degree] => PhD
                    )
                [13] => stdClass Object
                    (
                        [Id] => 37
                        [Degree] => Bachelor
                    )
                [14] => stdClass Object
                    (
                        [Id] => 42
                        [Degree] => PhD
                    )
                [17] => stdClass Object
                    (
                        [Id] => 50
                        [Degree] => Bachelor
                    )
                [18] => stdClass Object
                    (
                        [Id] => 52
                        [Degree] => Bachelor
                    )
                [19] => stdClass Object
                    (
                        [Id] => 53
                        [Degree] => Master
                    )
                [21] => stdClass Object
                    (
                        [Id] => 54
                        [Degree] => Master
                    )
                [23] => stdClass Object
                    (
                        [Id] => 55
                        [Degree] => Master
                    )
                [25] => stdClass Object
                    (
                        [Id] => 57
                        [Degree] => Bachelor
                    )
                [26] => stdClass Object
                    (
                        [Id] => 68
                        [Degree] => Master
                    )
                [28] => stdClass Object
                    (
                        [Id] => 72
                        [Degree] => Master
                    )
                [30] => stdClass Object
                    (
                        [Id] => 77
                        [Degree] => Bachelor
                    )
                [31] => stdClass Object
                    (
                        [Id] => 82
                        [Degree] => Bachelor
                    )
                [32] => stdClass Object
                    (
                        [Id] => 85
                        [Degree] => PhD
                    )
                [35] => stdClass Object
                    (
                        [Id] => 92
                        [Degree] => Master
                    )
                [37] => stdClass Object
                    (
                        [Id] => 100
                        [Degree] => Master
                    )
                [39] => stdClass Object
                    (
                        [Id] => 111
                        [Degree] => Bachelor
                    )
                [40] => stdClass Object
                    (
                        [Id] => 117
                        [Degree] => Master
                    )
                [42] => stdClass Object
                    (
                        [Id] => 123
                        [Degree] => Master
                    )
            )
    )
    

    What I want is to get the quantities for each distinct degree value as follows:

    Array
    (
        [Master] => 13
        [Bachelor] => 9
        [PhD] => 3
    )
    

    But in an Eloquent collection...

    How can I achieve this?

  • Jeremy Wadhams
    Jeremy Wadhams over 2 years
    I love this trick, thank you! You could simplify it one step more using the higher order map, like $degrees->groupBy('Degree')->map->count()
  • commadelimited
    commadelimited almost 2 years
    Too bad this was posted after the original accepted answer, this would be the best way to do it.
  • Sagar Gautam
    Sagar Gautam almost 2 years
    Hello sir, Is there any way to count number of these unique groups ? in your example count should be 3
  • Jarek Tkaczyk
    Jarek Tkaczyk almost 2 years
    @SagarGautam $degrees->groupBy(..)->count() will do the trick
  • Jarek Tkaczyk
    Jarek Tkaczyk almost 2 years
    @JeremyWadhams a bit late on my part, but thanks for your comment! Feel free to EDIT existing answers with such improvements - I'm sure everyone will appreciate your effort!
  • Sagar Gautam
    Sagar Gautam almost 2 years
    @JarekTkaczyk count doesn;t work with group by !
  • Julio Popócatl over 1 year
    You are falling to de DRY principle