Laravel - 资源计数月份日期

Laravel - Resource count month dates

我使用 Laravel eloquent 模型从数据库中获取数据。获取最近 6 个月的历史记录的所有用户。

数据库结果:

 {
            "id": 2,
            "permissions": 3,
            "is_banned": 0,
            "datetime_last_logged": "2020-04-20 09:59:25",
            "last_login_ip": "127.0.0.1",
            "is_deleted": 0,
            "logged": [
                {
                    "id": 9,
                    "user_id": 2,
                    "datetime_logged": "2020-04-20T07:59:22.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 10,
                    "user_id": 2,
                    "datetime_logged": "2020-04-18T07:59:22.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 11,
                    "user_id": 2,
                    "datetime_logged": "2020-01-20T08:59:23.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 12,
                    "user_id": 2,
                    "datetime_logged": "2020-03-20T08:59:25.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                }
            ]

我需要从我的记录字段中获取计数值,例如: October - 0, December - 0, January - 1, February - 0, March -1, April - 2

我该怎么做?

如果您要大量处理这些数据,我建议您在 table 中创建一个新列,以便您可以更轻松地进行过滤。

您可以获得 Carbon 的月份 :

$date = Carbon::parse('2020-03-20T08:59:25.000000Z')->format('F');

输出:

March

另外,你可以让foreach:

$logs= [];
foreach($users as $user){
  $date = $user->datetime_logged;
  $month = Carbon::parse($date)->format('F');
  $logs [] = $month;
}

这里有所有月份的数组,你只需要计算所有月份:

$count = array_count_values($logs);

输出:

Array
(
  [January] => 2
  [February] => 2
)

https://www.php.net/manual/en/function.array-count-values.php

如果你已经有了集合,你可以使用 Laravels 原生 Collection class 将项目按各自的月份分组,然后映射到分组数组以计算值:

collect($dbResult['logged'])
    ->groupBy(function ($item, $key) {
        return \Carbon\Carbon::parse($item['datetime_logged'])->month;
    })
    ->map(function ($item, $key) {
        return collect($item)->count();
    });

这个returns这样一个集合,以月数(从1开始)为键,分组集合中出现的次数为值:

如果你喜欢,你可以将 groupBy 操作的结果更改为

return \Carbon\Carbon::parse($item['datetime_logged'])->format('F');

所以它 returns 月份的名称而不是它的编号。


我的糟糕解决方案满足您要求自六个月以来的所有月份都已满:

$monthsInterval = \Carbon\CarbonPeriod::create(today()->subMonths(5), '1 month', today());

$placeholder = collect($monthsInterval)->mapWithKeys(function ($item, $key) {
    return [$item->format('F') => 0];
});

$userLogInsPerMonth = collect($dbResult['logged'])
    ->groupBy(function ($item, $key) {
        return \Carbon\Carbon::parse($item['datetime_logged'])->format('F');
    })
    ->map(function ($item, $key) {
        return collect($item)->count();
    });

dd($placeholder->merge($userLogInsPerMonth));

这个怪物 returns 是这样的: