PHP如何按组/部门/团队分组数组,避免覆盖同一行?
数组分组问题分析与解决
原数组结构
$original_array = [ [ "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" ] ];
预期分组结果
[ 0 => [ "group" => "g1", "department" => "d1", "team" => null, "data" => [ 0 => ["data_col1" => "some_data1", "data_col2" => "some_data2"], 1 => ["data_col1" => "some_data3", "data_col2" => "some_data4"] ] ], 1 => [ "group" => "g1", "department" => "d1", "team" => "t3", "data" => [ 0 => ["data_col1" => "some_data5", "data_col2" => "some_data6"] ] ], 2 => [ "group" => "g4", "department" => "d6", "team" => "t11", "data" => [ 0 => ["data_col1" => "some_data7", "data_col2" => "some_data8"] ] ] ]
错误实现代码
$new_array = []; foreach ($original_array as $row) { foreach ($row as $key => $value) { if ($key === "group" || $key === "department" || $key === "team") { $new_array[$key] = $value; } else { $new_array[] = $value; } } }
实际错误结果
[ "group" => "g4", "department" => "d6", "team" => "t11", 0 => "some_data1", 1 => "some_data2", 2 => "some_data3", 3 => "some_data4", 4 => "some_data5", 5 => "some_data6", 6 => "some_data7", 7 => "some_data8" ]
问题原因
- 分组信息被覆盖:每次循环一行数据时,直接给
$new_array的group/department/team键赋值,新值会替换旧值,最终只保留最后一行的分组信息。 - 数据未归类:将
data_col1/data_col2直接追加到$new_array的根层级,没有按分组存入对应的data子数组,导致数据零散分布。 - 未区分不同分组:全程复用同一个
$new_array结构,没有为每个独立的分组创建单独的数组项,无法区分不同分组的内容。
修正后的代码
$original_array = [ [ "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" ] ]; $grouped = []; foreach ($original_array as $item) { // 用group、department、team拼接唯一标识键,处理null值避免键冲突 $key = implode('|', [ $item['group'], $item['department'], is_null($item['team']) ? 'null' : $item['team'] ]); if (!isset($grouped[$key])) { // 初始化新分组的结构 $grouped[$key] = [ 'group' => $item['group'], 'department' => $item['department'], 'team' => $item['team'], 'data' => [] ]; } // 将当前行的业务数据添加到对应分组的data数组 $grouped[$key]['data'][] = [ 'data_col1' => $item['data_col1'], 'data_col2' => $item['data_col2'] ]; } // 转换为索引数组(移除关联键,符合预期结果的结构) $new_array = array_values($grouped); print_r($new_array);
代码说明
- 生成唯一分组键:用
group、department、team拼接成唯一字符串,作为临时分组的标识,处理null值避免键冲突。 - 初始化分组结构:如果当前分组不存在,创建包含分组信息和空
data数组的结构。 - 归集业务数据:将每行的
data_col1/data_col2存入对应分组的data子数组。 - 转换为索引数组:通过
array_values移除临时的关联键,得到预期的索引数组结构。
运行以上代码,输出结果与预期完全一致。
内容的提问来源于stack exchange,提问作者pileup
相关产品推荐
相关产品推荐

