扩展代码:对多维 PHP 数组进行分组并计算每个数组元素的特定键的总和

Extended code: Grouping multidimensional PHP array and calculating sum of a particular keys for each array element

这实际上是@RomanPerekhrest 在此处发布的原始代码的扩展版本:

我尝试了代码并尝试将其扩展到下一个级别。在某种程度上我成功了。

除了现有的 "companies" 子数组之外,我还添加了一个名为 "holders" 的子数组。然后计算 "companies" 子数组的 "capacity_share" 和 "holders" 子数组的 "holder_share" 的总和。

而且效果非常好。我在下面添加扩展代码:

考虑以下分配给变量的数组:$projects_group_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] => C1                                   
                                [capacity_share] => 14                                    
                                [project_year] => 2016
                            )

                    ),
                [holders] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [project_id] => 1                                    
                                [holder_type] => H1                           
                                [holder_share] => 12                                    
                                [project_year] => 2016
                            )

                        [1] => Array
                            (
                                [id] => 2
                                [project_id] => 1                                    
                                [holder_type] => H2                                 
                                [holder_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
                            )

                    ),
                    [holders] => Array
                    (
                        [0] => Array
                            (
                                [id] => 3
                                [project_id] => 2                                 
                                [holder_type] => H1                           
                                [holder_share] => 12                                    
                                [project_year] => 2016
                            )

                        [1] => Array
                            (
                                [id] => 4
                                [project_id] => 2                                   
                                [holder_type] => H2                                 
                                [holder_share] => 14                                    
                                [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
                            )

                    ),
                    [holders] => Array
                    (
                        [0] => Array
                            (
                                [id] => 5
                                [project_id] => 3                                
                                [holder_type] => H1                           
                                [holder_share] => 12                                    
                                [project_year] => 2014
                            )

                        [1] => Array
                            (
                                [id] => 6
                                [project_id] => 3                                   
                                [holder_type] => H2                                 
                                [holder_share] => 14                                    
                                [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
                            )

                    ),
                    [holders] => Array
                    (
                        [0] => Array
                            (
                                [id] => 7
                                [project_id] => 4                                
                                [holder_type] => H1                           
                                [holder_share] => 12                                    
                                [project_year] => 2014
                            )

                        [1] => Array
                            (
                                [id] => 8
                                [project_id] => 4                                   
                                [holder_type] => H2                                 
                                [holder_share] => 14                                    
                                [project_year] => 2014
                            )

                    )

            )

    )

) 

使用下面的代码我得到了完美的结果:

$sumData = array_map('prepare_data', $projects_group_by_year);
print_r($sumData);
exit;

function prepare_data($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;
$arr['H2_capacity_sum'] = $arr['H1_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'];

    $h_shares = array_column($item['holders'], 'holder_share', 'holder_type');
    $arr['H1_share_sum'] += $h_shares['H1'];
    $arr['H2_share_sum'] += $h_shares['H2'];
}

return $arr;
}

但我的代码在两种情况下无法正常工作:

第一个条件:

如果我添加具有相同 [company_type] => 值对的所有子数组。然后它显示以下通知:

注意:未定义索引:C2

[companies] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [project_id] => 1                                    
                                [company_type] => C1  //Notice here                        
                                [capacity_share] => 12                                    
                                [project_year] => 2016
                            )

                        [1] => Array
                            (
                                [id] => 2
                                [project_id] => 1                                    
                                [company_type] => C1  //Notice here                                 
                                [capacity_share] => 14                                    
                                [project_year] => 2016
                            )

                    )

第二个条件:

如果我添加多个具有相同 [company_type] => 值对的子数组,那么它只会考虑最后一个 [company_type] => 值对来添加 [capacity_share]。例如,它在下面的情况下使用 [capacity_share] => 15 并且不考虑 [capacity_share] => 14.

[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  //Notice here                                  
                                [capacity_share] => 14                                    
                                [project_year] => 2016
                            ),
                        [2] => Array
                            (
                                [id] => 3
                                [project_id] => 1                                    
                                [company_type] => C2  //Notice here                                
                                [capacity_share] => 15                                   
                                [project_year] => 2016
                            )

                    )

过去几天我正在努力解决上述问题。

下面是我尝试完成这项工作的代码片段之一:

function prepare_data($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;
$arr['H2_share_sum'] = $arr['H1_share_sum'] = 0;

foreach ($v as $item) {// iterating through the nested items
    $c_capacities = array_column($item['companies'], 'capacity_share', 'company_type');
    if(isset($c_capacities['company_type'])){
        $arr['C1_capacity_sum'] += $c_capacities['company_type'];
    }
    if(isset($c_capacities['C2'])){
        $arr['C2_capacity_sum'] += $c_capacities['C2'];
    }


    $h_shares = array_column($item['holders'], 'holder_share', 'holder_type');
    $arr['H1_share_sum'] += $s_capacities['H1'];
    $arr['H2_share_sum'] += $s_capacities['H2'];
}

return $arr;
}

有谁知道我做错了什么,我该如何解决以上两个问题?

谢谢。

这是解决方案:)

$sumData = array_map('prepare_data', $projects_grouped_by_year);
function prepare_data($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;
    $arr['H2_capacity_sum'] = $arr['H1_capacity_sum'] = 0;

    foreach ($v as $item) {
        // summing up companies shares
        $c_types = array_column($item['companies'], 'company_type');
        $c_shares = array_column($item['companies'], 'capacity_share');
        foreach ($c_types as $k => $v) {
            $arr[$v ."_capacity_sum"] += $c_shares[$k];
        }
        // summing up holders shares
        $h_types = array_column($item['holders'], 'holder_type');
        $h_shares = array_column($item['holders'], 'holder_share');
        foreach ($h_types as $k => $v) {
            $arr[$v ."_capacity_sum"] += $h_shares[$k];
        }        
    }

    return $arr;
}

print_r($sumData);