Neelkanth Kaushik - 1 year ago 57

PHP Question

I had an array which had data about all projects.

I needed to group the array by 'year_actual' element.

I have successfully done this grouping using a php function “array_group_by” which is available here: https://gist.github.com/mcaskill/baaee44487653e1afc0d

Here is my grouped array which I assigned to a variable: $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

)

)

)

)

)

I am manipulating above array to create a new following resultant array:

I will create a new array and insert the calculated values in this new array:

`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

)

);

I have succeeded in calculating the field “project_capacity_sum” using the below code:

`$projectCapacitySum = array_map(function($data) {`

return array_sum(array_column($data, 'project_capacity'));

}, $projects_grouped_by_year);

But I am struggling to calculate other fields for the last two days.

The only useful columns to me are following:

[project_capacity]

and

[year_actual]

Inside "companies" sub array

[company_type]

and

[capacity_share]

Basically I am trying group the array by "year_actual" (which i have already done)

Then find the total "project_capacity" in each year and also total "capacity_share" for each "company_type" in each year. I hope this makes sense.

There is no problem if we use column [project_year] inside the [companies] sub array to achieve the desired output.

I know that I have to do another group by inside the companies sub array..and I am still trying to do so.

I am not concerned about code efficiency or optimization at this point. I am just looking for a working logic.

I am asking for help. Please help me with this.

Thanks.

Answer Source

To get the needed result extend your initial solution (`array_map`

+ `array_sum`

+ `array_column`

) with the following approach:

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

The output:

```
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
)
)
```