You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤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
}

需求:

  1. 按消息类型(MMS/SMS)过滤数据
  2. 按sentAt字段的月份统计数量
  3. 生成长度为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:07:27