我正在尝试按列值对 3 维数组中的行数据进行分组,并对每个相应组中的子数组数据求和。
[
[
'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 ],
],
]
期望的输出:
[
[
'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 ],
],
]
我假设如下:
desc_topic
子数组(例如,它们在每个实例中都具有相同的Apple/Banana/Orange值。qtd_posts
子数组在相同的对应槽中具有要分组的值(例如,所有“1”条目要加在一起,所有“2”条目加在一起,等等)如果适用,那么这样的事情应该有效:
$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;
}
}
我已经扩展了输入数据的可变性,因为我认为在实际项目中拥有唯一的子数组列是现实的。
为了更简单地访问行数据,我建议调用
extract()
来生成单个变量。
如果第一次遇到
name
,只需将整行保存在结果数组中(使用临时键,以便更容易识别属于同一组的后续行)。
对于同一组中的后续行,迭代
desc_topic
子数组中的条目。如果在组的 desc_topic
子数组中找到当前值,只需将相关的 qtd_posts
值添加到适当保存的 qtd_posts
值。否则,它是一个独特的主题,必须向该组的 desc_topic
和 qtd_posts
子数组添加一个新元素。
代码:(演示)
$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));