如何从 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 的集合中计算不同的值?的主要内容,如果未能解决你的问题,请参考以下文章