对多维PHP数组进行分组,并为每个数组元素计算特定键的和


Grouping multidimensional PHP array and calculating sum of a particular key for each arrays element

我有一个包含所有项目数据的数组。

我需要按'year_actual'元素对数组进行分组。

我已经成功地完成了这个分组使用php函数"array_group_by"在这里可用:https://gist.github.com/mcaskill/baaee44487653e1afc0d

这是我的分组数组,我分配给一个变量:$projects_grouped_by_year

Array
(
    [2016] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [project_name] => P1                    
                    [project_capacity] => 100                    
                    [year_actual] => 2016                    
                    [companies] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 1
                                    [project_id] => 1                                    
                                    [company_type] => C1                           
                                    [capacity_share] => 12                                    
                                    [project_year] => 2016
                                )
                            [1] => Array
                                (
                                    [id] => 2
                                    [project_id] => 1                                    
                                    [company_type] => C2                                    
                                    [capacity_share] => 14                                    
                                    [project_year] => 2016
                                )
                        )
                )
            [1] => Array
                (
                    [id] => 2
                    [project_name] => P2                    
                    [project_capacity] => 200                    
                    [year_actual] => 2016                    
                    [companies] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 3
                                    [project_id] => 2                                    
                                    [company_type] => C2                                    
                                    [capacity_share] => 15                                    
                                    [project_year] => 2016
                                )
                            [1] => Array
                                (
                                    [id] => 4
                                    [project_id] => 2                                    
                                    [company_type] => C1                                    
                                    [capacity_share] => 16                                    
                                    [project_year] => 2016
                                )
                        )
                )
        )
    [2014] => Array
        (
            [0] => Array
                (
                    [id] => 3
                    [project_name] => P3                    
                    [project_capacity] => 300                    
                    [year_actual] => 2014                    
                    [companies] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 5
                                    [project_id] => 3                                    
                                    [company_type] => C1                                    
                                    [capacity_share] => 20                                    
                                    [project_year] => 2014
                                )
                            [1] => Array
                                (
                                    [id] => 6
                                    [project_id] => 3                                    
                                    [company_type] => C2                                  
                                    [capacity_share] => 22                                    
                                    [project_year] => 2014
                                )
                        )
                )
            [1] => Array
                (
                    [id] => 4
                    [project_name] => P4                    
                    [project_capacity] => 400                    
                    [year_actual] => 2014                    
                    [companies] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 7
                                    [project_id] => 4                                    
                                    [company_type] => C2                                    
                                    [capacity_share] => 11                                    
                                    [project_year] => 2014
                                )
                            [1] => Array
                                (
                                    [id] => 8
                                    [project_id] => 4
                                    [company_type] => C1
                                    [capacity_share] => 10
                                    [project_year] => 2014
                                )
                        )
                )
        )
) 

我正在操作上面的数组来创建一个新的结果数组:我将创建一个新数组,并将计算值插入到这个新数组中:

Array
(
    [0] => Array(
        //year_actual of project
        'year' => 2016,
         //[100+200] : sum of 'project_capacity' where year_actual = 2016 
        'project_capacity_sum' => 300,
         //[12+16] : sum of 'capacity_share' where company_type = C1 and project_year = 2016
        'C1_capacity_sum' => 28,
         //[14+15] : sum of 'capacity_share' where company_type = C2 and project_year = 2016
        'C2_capacity_sum' => 29
        )
    [1] => Array(
         //year_actual of project
        'year' => 2014,
         //[300+400] : sum of 'project_capacity' where year_actual = 2014
        'project_capacity_sum' => 700,
         //[20+10] : sum of 'capacity_share' where company_type = C1 and project_year = 2014
        'C1_capacity_sum' => 30,
         //[22+11] : sum of 'capacity_share' where company_type = C2 and project_year = 2014
        'C2_capacity_sum' => 33
        )
); 

我已经成功地计算了字段" project_capacity_sum "使用下面的代码:

$projectCapacitySum = array_map(function($data) { return array_sum(array_column($data, 'project_capacity')); }, $projects_grouped_by_year);

但这两天我一直在努力计算其他字段。

对我来说唯一有用的列如下:

[project_capacity]和(year_actual)

内部"companies"子数组

[company_type]和(capacity_share)

基本上我正在尝试组数组"year_actual"(这我已经做了)然后找出每年的总"project_capacity",以及每年每个"company_type"的总"capacity_share"。我希望这是有意义的。

如果我们在[companies]子数组中使用列[project_year]来实现所需的输出,则没有问题。

我知道我必须在companies子数组中做另一个group by ..我仍在尝试这样做。

在这一点上,我不关心代码效率或优化。我只是在寻找一个工作逻辑。

我在寻求帮助。请帮我一下。

谢谢。

要得到所需的结果,请使用以下方法扩展初始解(array_map + array_sum + array_column):

$sumData = array_map(function ($v) {
    $arr = ['year' => current(array_column($v, 'year_actual'))];
    $arr['project_capacity_sum'] = array_sum(array_column($v, "project_capacity"));
    $arr['C2_capacity_sum'] = $arr['C1_capacity_sum'] = 0;
    foreach ($v as $item) {  // iterating through the nested items
        $c_capacities = array_column($item['companies'], 'capacity_share', 'company_type');
        $arr['C1_capacity_sum'] += $c_capacities['C1'];
        $arr['C2_capacity_sum'] += $c_capacities['C2'];
    }
    return $arr;
}, $projects_grouped_by_year);
print_r($sumData);
输出:

Array
(
    [2016] => Array
        (
            [year] => 2016
            [project_capacity_sum] => 300
            [C1_capacity_sum] => 28
            [C2_capacity_sum] => 29
        )
    [2014] => Array
        (
            [year] => 2014
            [project_capacity_sum] => 700
            [C1_capacity_sum] => 30
            [C2_capacity_sum] => 33
        )
)