7

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?

3 Answers 3

28

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
// }
Sign up to request clarification or add additional context in comments.

5 Comments

I love this trick, thank you! You could simplify it one step more using the higher order map, like $degrees->groupBy('Degree')->map->count()
Hello sir, Is there any way to count number of these unique groups ? in your example count should be 3
@SagarGautam $degrees->groupBy(..)->count() will do the trick
@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!
@JarekTkaczyk count doesn;t work with group by !
12

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

2 Comments

Too bad this was posted after the original accepted answer, this would be the best way to do it.
Knowing both ways is good ;-) Thanks!
-2

Could also do the following:

$master = $degrees->sum('Master');
return $master;

$bachelor = $degrees->sum('Bachelor');
return $bachelor;

$phD = $degrees->sum('PhD');
return $phD;

1 Comment

You are falling to de DRY principle

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.