如何将含相同group/department/team的行合并为单组行迭代处理?
数组分组重构问题解答
问题描述
现有一个包含公司架构字段(group/department/team)和数据列的数组,示例如下:
[ ['group' => 'g1', 'department' => 'd1', 'team' => null, 'data_col1' => 'some_data1', 'data_col2' => 'some_data2'], ['group' => 'g1', 'department' => 'd1', 'team' => null, 'data_col1' => 'some_data3', 'data_col2' => 'some_data4'], ['group' => 'g1', 'department' => 'd1', 'team' => 't3', 'data_col1' => 'some_data5', 'data_col2' => 'some_data6'], ['group' => 'g4', 'department' => 'd6', 'team' => 't11', 'data_col1' => 'some_data7', 'data_col2' => 'some_data8'], ]
需要将其按相同的group/department/team分组,把对应的数据列聚合到data数组中,目标结构如下:
[ [ 'group' => 'g1', 'department' => 'd1', 'team' => null, 'data' => [ ['data_col1' => 'some_data1', 'data_col2' => 'some_data2'], ['data_col1' => 'some_data3', 'data_col2' => 'some_data4'] ] ], [ 'group' => 'g1', 'department' => 'd1', 'team' => 't3', 'data' => [ ['data_col1' => 'some_data5', 'data_col2' => 'some_data6'] ] ], [ 'group' => 'g4', 'department' => 'd6', 'team' => 't11', 'data' => [ ['data_col1' => 'some_data7', 'data_col2' => 'some_data8'] ] ] ]
一、数组转换实现方法
以PHP为例,通过遍历原数组生成唯一分组键,聚合对应数据列:
$originalArray = [ ['group' => 'g1', 'department' => 'd1', 'team' => null, 'data_col1' => 'some_data1', 'data_col2' => 'some_data2'], ['group' => 'g1', 'department' => 'd1', 'team' => null, 'data_col1' => 'some_data3', 'data_col2' => 'some_data4'], ['group' => 'g1', 'department' => 'd1', 'team' => 't3', 'data_col1' => 'some_data5', 'data_col2' => 'some_data6'], ['group' => 'g4', 'department' => 'd6', 'team' => 't11', 'data_col1' => 'some_data7', 'data_col2' => 'some_data8'], ]; $groupedArray = []; foreach ($originalArray as $item) { // 生成唯一分组键,用特殊标识处理null值避免分组错误 $groupKey = implode('|', [ $item['group'], $item['department'], $item['team'] ?? 'null_placeholder' ]); // 提取纯数据列(排除架构字段) $dataItem = array_diff_key($item, array_flip(['group', 'department', 'team'])); if (!isset($groupedArray[$groupKey])) { // 初始化分组结构 $groupedArray[$groupKey] = [ 'group' => $item['group'], 'department' => $item['department'], 'team' => $item['team'], 'data' => [] ]; } // 将数据列加入分组的data数组 $groupedArray[$groupKey]['data'][] = $dataItem; } // 重置数组索引(可选,根据需求保留关联键或转为索引数组) $groupedArray = array_values($groupedArray);
二、此类重构操作的效率问题
- 这类操作的时间复杂度是O(n)(n为原数组元素数量),属于线性遍历,绝大多数业务场景下效率完全够用。
- 性能消耗主要集中在分组键的字符串拼接和键值判断上。如果处理百万级以上的超大数组,可以优化分组键生成方式(比如用哈希值代替字符串拼接),但普通场景无需额外优化。
- 内存方面,只是对原数据的结构重组,不会产生额外数据量,内存开销可控。
三、处理相同架构行的最优方案
1. 数据源端分组(最优选择)
如果数据来自数据库,直接在SQL层面完成分组,避免应用层的数组遍历:
以MySQL为例,用JSON_ARRAYAGG聚合数据列:
SELECT `group`, department, team, JSON_ARRAYAGG(JSON_OBJECT('data_col1', data_col1, 'data_col2', data_col2)) AS data FROM your_table GROUP BY `group`, department, team;
查询结果直接符合目标结构,性能和效率远高于应用层处理。
2. 应用层分组(非数据库场景)
如果数据来自API或其他非数据库来源,采用前文的遍历分组方法,注意:
- 确保分组键唯一,处理好
null值(比如用固定占位符代替); - 用
array_diff_key动态排除架构字段,适配数据列不固定的场景; - 超大数组场景下,用生成器(PHP的
yield)边遍历边输出,减少内存占用。
内容的提问来源于stack exchange,提问作者pileup
相关产品推荐
相关产品推荐

