Laravel集合对集合中的多个列求和

时间:2018-10-25 15:59:34

标签: laravel laravel-5

我一直在阅读有关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');

因为我假设这会导致集合上出现多个循环,否则我错了吗?

2 个答案:

答案 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目前不支持嵌套数组(即,对字段的点号访问不起作用)。