我收集了需要处理才能生成报告的数据
以下是提供的数据样本
$arrival_data = [
[
"arrival_date" => "09-Dec-2020",
"total_amount" => "10",
"total_traveller" => 6
],
[
"arrival_date" => "09-Dec-2020",
"total_amount" => "20",
"total_traveller" => 6
],
[
"arrival_date" => "10-Dec-2020",
"total_amount" => "40",
"total_traveller" => 3
]
];
我想处理上面的数据,因此它将按“arrival_date”分组并对数据求和,以便数据如下所示
$arrival_data = [
[
"arrival_date" => "09-Dec-2020",
"total_amount" => "30", // sum of 10 + 20
"total_traveller" => 6
],
[
"arrival_date" => "10-Dec-2020",
"total_amount" => "40",
"total_traveller" => 3
]
];
我还没有设法使用 laravel 集合生成预期的输出,我能得到的最接近的输出如下
{
"09-Dec-2020": 30,
"10-Dec-2020": 40
}
使用下面的代码
$collection = collect($arrival_data);
$num = $collection->groupBy('arrival_date')->map(function ($row) {
return $row->sum('total_amount');
});
return $num->toArray();
Laravel Collection 能够编写代码来按预期生成输出,或者需要通过循环数组和处理来使用不同的方法。
谢谢你
不要映射到总和,而是将要保留的字段映射到数组并对列求和并将其设置在数组中。要获取静态字段,请获取第一行,我们可以假设所有行都是相等的,因为它们已经分组。然后你将拥有与你想要实现的相同的数组结构。
$result = $collection->groupBy('arrival_date')
->map(function ($row) {
$firstRow = $row->first();
return [
'arrival_date' => $firstRow['arrival_date'],
'total_amount' => $row->sum('total_amount'),
'total_traveller' => $firstRow['total_traveller'],
];
})->values()
->all();
Group by 会将数组键映射到分组值,为了避免这种情况并收到预期结果,只需在集合上调用
->values()->all()
即可返回值。
可能有一种更奇特的方法来处理集合,但首先想到的是一个普通的旧 foreach 循环:
$arrival_data = [
[
'arrival_date' => '09-Dec-2020',
'total_amount' => '10',
'total_traveller' => 6
],
[
'arrival_date' => '09-Dec-2020',
'total_amount' => '20',
'total_traveller' => 6
],
[
'arrival_date' => '10-Dec-2020',
'total_amount' => '40',
'total_traveller' => 3
]
];
$grouped_arrival_data = [];
foreach ($arrival_data as $arrival_datum) {
if (!isset($grouped_arrival_data[$arrival_datum['arrival_date']])) {
$grouped_arrival_data['total_amount'] = (int) $arrival_datum['total_amount'];
$grouped_arrival_data['total_traveller'] = $arrival_datum['total_traveller'];
$grouped_arrival_data['arrival_date'] = $arrival_datum['arrival_date'];
} else {
$grouped_arrival_data['total_amount'] += (int) $arrival_datum['total_amount'];
$grouped_arrival_data['total_traveller'] += $arrival_datum['total_traveller'];
}
}
Laravel 的
reduce()
方法中的自定义函数是一种非常直接的方法,因为它只需一个循环即可提供所需的数组。
代码:(演示)
var_export(
$arrival_data->reduce(
function($result, $row) {
static $amts = [];
if (!isset($amts[$row['arrival_date']])) {
$amts[$row['arrival_date']] = $row;
$result[] =& $amts[$row['arrival_date']];
} else {
$amts[$row['arrival_date']]['total_amount'] += $row['total_amount'];
}
return $result;
}
)
);
如果您喜欢使用大量辅助方法,这里有一种方法可以最大限度地减少本机 PHP 语法,并倾向于链接 Laravel 方法:(Demo)
var_export(
$arrival_data
->groupBy('arrival_date')
->map(fn($row) => collect($row->first())->put('total_amount', $row->sum('total_amount')))
->values()
->toArray()
);
说实话,我确实希望能够通过添加
values()
作为 false
的 preserveKeys
参数来省略 groupBy()
调用,但这似乎并没有删除第一级分组键。