如何过滤Laravel集合并按月份统计MMS/SMS数量适配Chart.js?
Laravel集合按消息类型+月份统计,生成Chart.js适配数组
问题场景
现有如下Illuminate\Support\Collection集合数据:
Illuminate\Support\Collection {#456 ▼ // app\Http\Controllers\UserController.php:42 #items: array:4 [▼ 0 => array:10 [▼ "to" => "12145" "from" => "1833" "type" => "MMS" "smsCount" => 3 "status" => "PENDING" "error" => "No Error" "description" => "Message sent, waiting for delivery report" "sentAt" => "2024-04-06T05:29:20.791Z" "doneAt" => "2024-04-06T05:29:22.779Z" "messageId" => "27a13e81" ] 1 => array:10 [▼ "to" => "1215" "from" => "18334" "type" => "MMS" "smsCount" => 3 "status" => "DELIVERED" "error" => "No Error" "description" => "Message delivered to handset" "sentAt" => "2024-04-06T05:26:44.683Z" "doneAt" => "2024-04-06T05:26:46.423Z" "messageId" => "ebb9330c" ] 2 => array:10 [▶] 3 => array:10 [▶] ] #escapeWhenCastingToString: false }
需求:
- 按消息类型(
MMS/SMS)过滤数据 - 按
sentAt字段的月份统计数量 - 生成长度为12的数组,对应1-12月,无数据的月份填0,比如
[0,0,0,4,0,0,0,0,0,0,0,0](表示4月有4条MMS)
用户尝试了以下代码,但未得到预期输出:
$selectedElements = new Collection($selectedElements); $filteredAndGrouped = $selectedElements ->where('type', 'MMS') ->groupBy(function ($item) { // Extract year and month from the date string $dateParts = explode('-', substr($item['sentAt'], 0, 10)); // Extract yyyy-mm from the date string return $dateParts[0] . '-' . $dateParts[1]; // Return yyyy-mm format });
解决方案
1. 封装通用统计方法(支持MMS/SMS)
function getMonthlyStats(Collection $collection, string $type): array { // 过滤指定类型,按月份分组并统计数量 $monthlyCounts = $collection ->where('type', $type) ->groupBy(function ($item) { // 用Carbon解析日期,直接获取月份数字(1-12) return \Carbon\Carbon::parse($item['sentAt'])->month; }) ->map(fn($group) => $group->count()) ->toArray(); // 初始化12个月的全0数组 $stats = array_fill(0, 12, 0); // 将统计结果填充到对应月份的索引位置(月份-1对应数组下标) foreach ($monthlyCounts as $month => $count) { $stats[$month - 1] = $count; } return $stats; }
2. 使用示例
// 统计MMS月度数据 $mmsStats = getMonthlyStats($selectedElements, 'MMS'); // 输出示例:[0,0,0,4,0,0,0,0,0,0,0,0] // 统计SMS月度数据 $smsStats = getMonthlyStats($selectedElements, 'SMS');
关键说明
- 用
Carbon解析日期比手动切割字符串更可靠,兼容所有标准日期格式 - 直接提取月份数字(1-12),后续只需减1就能匹配数组的0开始索引
- 先初始化全0数组再覆盖数据,确保数组长度固定为12,完全适配Chart.js的横轴顺序
内容的提问来源于stack exchange,提问作者Hola
相关产品推荐
相关产品推荐

