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

Apply reduce method for all properties of an object

我在 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);

我正在寻找一种适用于所有领域的方法。可能吗 ?这样我就不会重复 10 次相同的 reduce 函数

谢谢!

使用 collect 助手和 sum 方法:

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

你可以这样做:

[$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