如何从 Laravel 的集合中计算不同的值?

Posted

技术标签:

【中文标题】如何从 Laravel 的集合中计算不同的值?【英文标题】:How to count distinct values from a collection in Laravel? 【发布时间】:2016-06-25 14:58:09 【问题描述】:

我一直在努力研究如何从 Eloquent 中的集合中获取不同值的数量。

我一直在尝试几种方法,例如在docs 上找到的 unique()、values() 等。即使确实有 count() 方法,也没有方法可以获取不同值的计数。

例如,通过应用以下查询

$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://***.com/a/17006377/1883256*/
        ->get();

我得到了这个收藏:

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
                )

        )

)

因为,我只想获得最高学位(用户 ID 可能有多个历史学位),所以我应用了 unique() 方法,根据文档,它只留下第一个原始值,在我的情况下,我已经按层次结构对它们进行了排序:

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

现在我得到了以下集合(减少到 25 个项目,这正是总数):

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
                )

        )

)

我想要的是获得每个不同度数的数量,如下所示:

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

但在 Eloquent 合集中...

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

2021/L6+ 更新

感谢@JeremyWadhams

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

使用收集方法就是这样:

$degrees->groupBy('Degree')->map(function ($people) 
    return $people->count();
);

// Collection 
//   'Master' => 13,
//   'Bachelor' => 9,
//   'PhD' => 3
// 

【讨论】:

我喜欢这个技巧,谢谢!您可以使用更高阶的映射进一步简化它,例如 $degrees->groupBy('Degree')->map->count() 您好先生,有没有办法计算这些独特组的数量?在您的示例中,计数应为 3 @SagarGautam $degrees->groupBy(..)->count() 可以解决问题 @JeremyWadhams 我有点晚了,但感谢您的评论!随意编辑现有答案并进行此类改进 - 我相信每个人都会感谢您的努力! @JarekTkaczyk 计数不适用于 group by!【参考方案2】:

有一个名为 CountBy 的 Collection Helper,可以满足您的需要。

Collections CountBy

$degrees->countBy('Degree');

它会按预期返回

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

简单:D

【讨论】:

太糟糕了,这是在最初接受的答案之后发布的,这将是最好的方法。【参考方案3】:

还可以执行以下操作:

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

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

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

【讨论】:

你正在落入 de DRY 原则

以上是关于如何从 Laravel 的集合中计算不同的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何从不同的表中计算laravel

Laravel 集合从每个函数中检索变量结果

相关模型 eloquent laravel 中的自定义查询

Laravel - 从不同的表中获取总和并计算

如何从 laravel 的 eloquent 集合中获取外键

如何从 Laravel 集合中获取最小日期