对对象的所有属性应用reduce方法

问题描述

我在Laravel中有一个代表月度报告的对象。

  0 => array:20 [▼
    "id" => 43
    "operation_id" => 1
    "meter_id" => 3
    "period" => "monthly"      
    "total_conso" => "103.42"
    "total_autoconso" => "59.47"
    "total_grid" => "43.95"
    "bill" => "31.95"
    "grid_fee" => "26.97"
    "solar_turpe_tax_fee" => "4.99"
    "savings" => "4.41"
    "total_prod" => null
    "total_surplus" => null
    "autoconso_rate" => "57.5"
    "autoprod_rate" => null
    "surplus_rate" => null
    "date" => "2019-08-24T00:00:00.000000Z"
    "created_at" => "2019-08-24T00:00:00.000000Z"
    "updated_at" => "2020-10-01T15:03:38.000000Z"

我有一个包含12个对象的数组,每月一个

我正在计算年度报告值,并且我必须对每个字段的所有12个月求和。

我可以使用以下方法逐个字段地进行缩小:

$totalConso = $reports->reduce(function ($sum,$report) {
            return $sum + $report->total_conso;
        },0);

我正在寻找一种针对所有领域的方法。可能吗 ?这将使我不能重复使用相同的reduce函数10次

谢谢!

解决方法

您可以执行以下操作:

[$totalConso,$totalAutoConso] = collect(['total_conso','total_autoconso'])->map(fn ($property) => $reports->sum($property));

如果您希望每个总数都包含一个数组:

$totals = collect(['total_conso','total_autoconso'])->mapWithKeys(fn ($property) => [$property => $reports->sum($property)]);

这将为您提供所有总计的集合。

如果您不喜欢对total_*属性列表进行硬编码,则可以从模型的fillable属性列表中动态获取它们(假设您使用的是fillable属性):

$totals = collect(Report::make()->fillable)
    ->filter(fn ($property) => strpos($property,'total_') === 0)
    ->mapWithKeys(fn ($property) => [$property => $reports->sum($property)]);

演示:https://laravelplayground.com/#/snippets/ec3c662f-0ab9-4de8-8422-7bed2f054677

,

使用collect帮助器和sum方法:

$total = collect($reports)->sum('total_conso');