I need to add new elemets to my array when a new category
value is encountered. When a category
value is encountered after the first time, its value1
and value2
values should be added to the first encounter's respective values.
Also, in the result array, I no longer wish to keep the category
column. The category-grouping rows should use the category
value as its name
value.
Sample input:
$datas = [
[
'category' => 'Solution',
'name' => 'Name1',
'value1' => 20,
'value2' => 21
],
[
'category' => 'Solution',
'name' => 'Name2',
'value1' => 30,
'value2' => 31
],
[
'category' => 'Solution1',
'name' => 'Name3',
'value1' => 40,
'value2' => 41
]
];
Desired result:
[
['name' => 'Solution', 'value1' => 50, 'value2' => 52],
['name' => 'Name1', 'value1' => 20, 'value2' => 21],
['name' => 'Name2', 'value1' => 30, 'value2' => 31],
['name' => 'Solution1', 'value1' => 40, 'value2' => 41],
['name' => 'Name3', 'value1' => 40, 'value2' => 41]
]
I tried like this:
private function groupByProductSuperCategory($datas)
{
$return = [];
foreach ($datas as $data) {
$return[$data['category']][$data['name']] = array_sum(array_column('category', $data);
}
return $return;
}
The idea is to calculate first all sum values for by category, and after that just put values from name like another array. Have you an idea of how to do that?
From the posted array... To end in the desired array, there is some tiny fixes to do first. But I assumed it was due to typos while copying here...
So here is the array I started with:
$result = [
0 => [
"category" => 'Solution',
"name" => 'Name1',
"value1" => 20,
"value2" => 21
],
1 => [
"category" => 'Solution',
"name" => 'Name2',
"value1" => 30,
"value2" => 31
],
2 => [
"category" => 'Solution1',
"name" => 'Name3',
"value1" => 40,
"value2" => 41
]
];
Now, that re-organization of the data is a bit more complex than it looks... You need to perform several loops to:
So here is the code I ended with:
function groupByProductSuperCategory($datas){
$category = [];
$return = [];
// Find distinct categories
foreach ($datas as $data) {
if(!in_array($data["category"],$category)){
array_push($category,$data["category"]);
}
}
// For each distinct category, add the sum item and the single items
foreach ($category as $cat) {
// Get the sums
if(!in_array($cat,$return)){
$sum1 = 0;
$sum2 = 0;
foreach ($datas as $data) {
if($data["category"] == $cat){
$sum1 += $data["value1"];
$sum2 += $data["value2"];
}
}
}
// Push the sums in the return array
array_push($return,[
"name" => $cat,
"value1" => $sum1,
"value2" => $sum2,
]);
// Push the single elements
foreach ($datas as $data) {
if($cat == $data["category"]){
array_push($return,[
"name" => $data["name"],
"value1" => $data["value1"],
"value2" => $data["value2"],
]);
}
}
}
return $return;
}
Here is a PHPFiddle to try it out... Hit [F9] to run.
It is much more direct, efficient, and readable to implement a single loop and push reference variables into the result array to allow summing based on shared categories without keeping track of the actual indexes of the category rows.
Code: ( Demo )
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row['category']])) {
$ref[$row['category']] = [
'name' => $row['category'],
'value1' => 0,
'value2' => 0
];
$result[] = &$ref[$row['category']];
}
$ref[$row['category']]['value1'] += $row['value1'];
$ref[$row['category']]['value2'] += $row['value2'];
unset($row['category']);
$result[] = $row;
}
var_export($result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.