Reputation: 1
I am trying to group row data from a 3-dimensional array by a column value and sum subarray data in each respective group.
[
[
'name' => 'Edward Foo',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [10, 20, 50 ],
],
[
'name' => 'Michael Max',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [10, 10, 10 ],
],
[
'name' => 'Edward Foo',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [5, 10, 30 ],
],
[
'name' => 'Michael Max',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [8, 8, 20 ],
],
]
Desired output:
[
[
'name' => 'Edward Foo',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [15, 30, 80 ],
],
[
'name' => 'Michael Max',
'desc_topic' => ['Apple', 'Banana', 'Orange'],
'qtd_posts' => [18, 18, 30 ],
],
]
Upvotes: -1
Views: 2715
Reputation: 47874
I've expanded the variability of the input data because I think it is realistic to have unique columns the subarrays in a real project.
To enable simpler access to row data, I recommend calling extract()
to generate individual variables.
If a name
is encountered for the first time, merely save the whole row in the result array (with a temporary key to make it easier to identify subsequent rows belonging to the same group).
For subsequent rows within the same group, iterate the entries in the desc_topic
subarray. If the current value is found in the group's desc_topic
subarray, merely add the related qtd_posts
value to the appropriate saved qtd_posts
value. Otherwise, it is a unique topic and a new element must be added to the desc_topic
and qtd_posts
subarrays for the group.
Code: (Demo)
$result = [];
foreach ($array as $row) {
extract($row);
if (!isset($result[$name])) {
$result[$name] = $row;
} else {
foreach ($desc_topic as $i => $topic) {
$index = array_search($topic, $result[$name]['desc_topic']);
if ($index === false) { // create new column in both subarrays
$result[$name]['desc_topic'][] = $topic;
$result[$name]['qtd_posts'][] = $qtd_posts[$i];
} else { // sum preexisting value with new value in on same topic
$result[$name]['qtd_posts'][$index] += $qtd_posts[$i];
}
}
}
}
var_export(array_values($result));
Upvotes: 0
Reputation: 360572
I'm assuming the following:
desc_topic
sub-array (e.g. they all have the same Apple/Banana/Orange values for every instance.qtd_posts
sub-array has the to-be-grouped values in the same corresponding slots (e.g. all '1' entries are to be summed together, all '2' entries summed together, etc...)If that applies, then something like this should work:
$newarr = array();
$reverse_map = array();
foreach($array as $idx => $entry) {
if (isset($reverse_map[$entry['name']]) {
// have we seen this name before? retrieve its original index value
$idx = $reverse_map[$entry['name']];
} else {
// nope, new name, so store its index value
$reverse_map[$entry['name']] = $idx;
}
// copy the 'constant' values
$newarr[$idx]['name'] = $entry['name'];
$newarr[$idx]['desc_top'] = $entry['desc_topic'];
// sum the qtd_post values to whatever we previously stored.
foreach($entry['qtd_posts'] as $x => $y) {
$newarr[$idx]['qtd_posts'][$x] += $y;
}
}
Upvotes: 1