Extended code: Grouping multidimensional PHP array

2019-08-02 04:43发布

问题:

This is actually a extended version of the original code posted by @RomanPerekhrest here: Grouping multidimensional PHP array and calculating sum of a particular key for each arrays element

I played with the code and tried to extend it to next level. And to some extent I succeeded.

What is did is that I added one more sub array called "holders" in addition to the existing "companies" sub array. And then calculated the sum of "capacity_share" from "companies" sub array and "holder_share" from "holders" sub array.

And it worked like a charm. I am adding the extended code below:

Consider the below array assigned to variable: $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
                            )

                    )

            )

    )

) 

And using code below I get the perfect result:

$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;
}

But my code is not working well under two conditions:

First condition:

If I add all sub arrays with same [company_type] => value pair. Then it displays following notice:

Notice: Undefined index: 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
                            )

                    )

Second Condition:

If I add more than one sub array with same [company_type] => value pair, then it only considers the last [company_type] => value pair for adding the [capacity_share]. For example, it uses [capacity_share] => 15 in the case below and does not consider [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
                            )

                    )

I am working on fixing above issues for past few days.

Below is one of the code snippets I tried to make this work:

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;
}

Does any one know what I am doing wrong and how can I fix the above two issues?

Thanks.

回答1:

And here is the solution :)

$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);