我一直在阅读有关Laravel中收藏的信息。目前,我知道如何使用它,但是我对sum()
函数有疑问。
根据文档,它可以像这样使用:
collect([1, 2, 3, 4, 5])->sum();
也这样:
$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176],
['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
]);
$collection->sum('pages');
这很好,我了解,但是现在我有了一个带有嵌套对象的数组,我想知道如何在laravel中实现这样的功能:
$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176, 'price' => 100.00],
['name' => 'JavaScript: The Definitive Guide', 'pages' => price, 'pages' => 150.00],
]);
$collection->sum(['pages', 'prices']);
显然可以返回以下任何一个数组:
[1272, 250]
或在这样的集合/对象上:
{"total_pages": 1272, "total_price": 250}
简而言之,我想知道如何求和并返回laravel集合中多列的结果,而不是重复两次:
$collection->sum('pages');
$collection->sum('price');
因为我假设这会导致集合上出现多个循环,否则我错了吗?
答案 0 :(得分:2)
您需要使用pipe
方法将集合传递给回调。在回调中,您可以实现想要执行的操作。
$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176, 'price' => 100.00],
['name' => 'JavaScript: The Definitive Guide', 'pages' => 314, 'price' => 150.00]
]);
$result = $collection->pipe(function ($collection) {
return collect([
'total_pages' => $collection->sum('pages'),
'total_price' => $collection->sum('price'),
]);
});
答案 1 :(得分:1)
查看code behind the sum() function
,我们可以看到内部使用$collection->reduce()
来收集数据。因此,我们应该能够使用相同的代码来实现您想要的目标:
return $collection->reduce(function ($result, $item) {
if ($result === null) {
$result = [
'pages' => 0,
'price' => 0,
];
}
$result['pages'] += $item['pages'];
$result['price'] += $item['price'];
return $result;
}, 0);
要获得更通用的解决方案,您还可以在其中一个服务提供商的Collection
类上创建一个宏:
Collection::macro('sumMultiple', function ($columns) {
return $this->reduce(function ($result, $item) use ($columns) {
if ($result === null) {
foreach ($columns as $column) {
$result[$column] = 0;
}
}
foreach ($columns as $column) {
$result[$column] += $item[$column];
}
return $result;
}, 0);
});
然后可以将新功能与$collection->sumMultiple(['pages', 'price'])
一起使用,您将收到类似['pages' => 123, 'price' => 234]
的结果。
请注意,sumMultiple
目前不支持嵌套数组(即,对字段的点号访问不起作用)。