PHP中如何对嵌套数组按分组聚合特定键值并求和
嵌套数组按指定维度分组聚合的PHP实现
给定如下嵌套数组结构:
Array ( [3] => Array ( [0] => Array ( [revenue_generated] => 4.5 [month_no] => 1 [client_id] => 428 [client_name] => Aljazeera pro [company_id] => 18 [partner_id] => 18 [partner_name] => itialuS India [engagements] => 3 [engagementsArr] => 787,925,347 [country_id] => 2 [country_name] => India [region_code] => S3 [region_id] => 3 [region_name] => Jamaica [employee_id] => 255 [email_id_office] => test@wallpostdev.com [staff_name] => Mark Smith [all_companies_id] => 18,18,18 ) [1] => Array ( [revenue_generated] => 65.4 [month_no] => 1 [client_id] => 2044 [client_name] => Test USA Lead 107 [company_id] => 19 [partner_id] => 19 [partner_name] => Jamaica Activation Partner [engagements] => 1 [engagementsArr] => 896 [country_id] => 112 [country_name] => Jamaica [region_code] => S3 [region_id] => 3 [region_name] => Jamaica [employee_id] => 273 [email_id_office] => smitit2018+747600_273@gmail.com [staff_name] => Raymond Larson [all_companies_id] => 19 ) [2] => Array ( [revenue_generated] => 14.169341894061 [month_no] => 2 [client_id] => 2046 [client_name] => Task [company_id] => 18 [partner_id] => 18 [partner_name] => itialuS India [engagements] => 1 [engagementsArr] => 897 [country_id] => 2 [country_name] => India [region_code] => S3 [region_id] => 3 [region_name] => Jamaica [employee_id] => 435 [email_id_office] => smitit2018+747600_435@gmail.com [staff_name] => Nithin sabu [all_companies_id] => 18 ) [3] => Array ( [revenue_generated] => 32.4 [month_no] => 2 [client_id] => 2048 [client_name] => Test USA Lead 120 [company_id] => 19 [partner_id] => 19 [partner_name] => Jamaica Activation Partner [engagements] => 1 [engagementsArr] => 898 [country_id] => 112 [country_name] => Jamaica [region_code] => S3 [region_id] => 3 [region_name] => Jamaica [employee_id] => 275 [email_id_office] => smitit2018+747600_275@gmail.com [staff_name] => Jennifer Connelly [all_companies_id] => 19 ) ) [4] => Array ( [0] => Array ( [revenue_generated] => 179.01284109149 [month_no] => 1 [client_id] => 2090 [client_name] => Eng.Cancelletion Test1 [company_id] => 18 [partner_id] => 21 [partner_name] => itialuS India Partner [engagements] => 1 [engagementsArr] => 910 [country_id] => 80 [country_name] => India Country [region_code] => A1 [region_id] => 4 [region_name] => Asia [employee_id] => 255 [email_id_office] => test@wallpostdev.com [staff_name] => Jhon Smith [all_companies_id] => 18 ) [1] => Array ( [revenue_generated] => 40.01284109149 [month_no] => 1 [client_id] => 2090 [client_name] => Eng.Cancelletion Test1 [company_id] => 18 [partner_id] => 21 [partner_name] => itialuS India Partner [engagements] => 1 [engagementsArr] => 910 [country_id] => 80 [country_name] => India Country [region_code] => A1 [region_id] => 4 [region_name] => Asia [employee_id] => 255 [email_id_office] => test@wallpostdev.com [staff_name] => Jhon Smith [all_companies_id] => 18 ) [2] => Array ( [revenue_generated] => 204.7893258427 [month_no] => 2 [client_id] => 2095 [client_name] => TIME TODAY 3 [company_id] => 18 [partner_id] => 21 [partner_name] => itialuS India Partner [engagements] => 1 [engagementsArr] => 915 [country_id] => 80 [country_name] => India Country [region_code] => A1 [region_id] => 4 [region_name] => Asia [employee_id] => 446 [email_id_office] => bala@wall.com [staff_name] => Balaguru Swamy [all_companies_id] => 18 ) [3] => Array ( [revenue_generated] => 65.7893258427 [month_no] => 2 [client_id] => 2095 [client_name] => TIME TODAY 3 [company_id] => 18 [partner_id] => 21 [partner_name] => itialuS India Partner [engagements] => 1 [engagementsArr] => 915 [country_id] => 80 [country_name] => India Country [region_code] => A1 [region_id] => 4 [region_name] => Asia [employee_id] => 446 [email_id_office] => bala@wall.com [staff_name] => Balaguru Swamy [all_companies_id] => 18 ) ) )
需要将其处理为如下格式的输出:
Array ( [3] => Array ( [0] => Array ( [revenue_generated] => 69.9 [month_no] => 1 [engagements] => 4 [engagementsArr] => 787,925,347,896 [region_code] => S3 [region_id] => 3 [region_name] => Jamaica ) [1] => Array ( [revenue_generated] => 46.56 [month_no] => 2 [engagements] => 2 [engagementsArr] => 897,898 [region_code] => S3 [region_id] => 3 [region_name] => Jamaica ) ) [4] => Array ( [0] => Array ( [revenue_generated] => 229.02 [month_no] => 1 [engagements] => 2 [engagementsArr] => 910,911 [region_code] => A1 [region_id] => 4 [region_name] => Asia ) [1] => Array ( [revenue_generated] => 270.56 [month_no] => 2 [engagements] => 2 [engagementsArr] => 915,916 [region_code] => A1 [region_id] => 4 [region_name] => Asia ) ) )
具体需求
- 按外层数组键(如3、4)和
month_no进行分组 - 对每组内的
revenue_generated值求和 - 合并
engagementsArr并统计其中唯一engagements的数量 - 保留
region_code、region_id、region_name字段
尝试的错误代码
$salesDataArr = []; foreach($result as $key => $value) { $newkey = 'month_no'; foreach($value AS $val){ $salesChartArray[$key]=[]; if(empty($salesChartArray[$key])) { $salesChartArray[$key] = $re; $salesChartArray[$key]['month_no'] = $re['month_no']; $salesChartArray[$key]['revenue_generated'] = 0; } $salesChartArray[$key]['engagementsArr'] = $salesChartArray[$key]['engagementsArr'] .','. $re['engagementsArr']; $salesChartArray[$key]['all_companies_id'] = $salesChartArray[$key]['all_companies_id'] .','. $re['all_companies_id']; $salesChartArray[$key]['engagements'] = $this->countUniqueEngagement($salesChartArray[$key]['engagementsArr']); $salesChartArray[$key]['revenue_generated'] += $re['revenue_generated']; if(array_key_exists($newkey, $val)){ $salesDataArr[$key][$val[$newkey]] = $salesChartArray[$key]; $salesDataArr[$key][$val[$newkey]]['engagementsArr'] = $salesChartArray[$key]['engagementsArr']; $salesDataArr[$key][$val[$newkey]]['all_companies_id'] = $salesChartArray[$key]['all_companies_id']; $salesDataArr[$key][$val[$newkey]]['engagements'] = $salesChartArray[$key]['engagements']; $salesDataArr[$key][$val[$newkey]]['revenue_generated'] = $salesChartArray[$key]['revenue_generated']; } } } public function countUniqueEngagement($engagements){ $exploded = explode(",", $engagements); return count(array_filter(array_unique($exploded))); }
正确的PHP实现方案
<?php // 处理数组的核心函数 function processSalesData($result) { $processedData = []; // 遍历外层数组的每个区域分组(键3、4等) foreach ($result as $regionKey => $items) { $monthGroups = []; // 遍历当前区域下的每条数据 foreach ($items as $item) { $monthNo = $item['month_no']; // 如果当前月份分组不存在,初始化结构 if (!isset($monthGroups[$monthNo])) { $monthGroups[$monthNo] = [ 'revenue_generated' => 0, 'month_no' => $monthNo, 'engagements' => [], // 用数组存储唯一的engagement ID,便于去重 'region_code' => $item['region_code'], 'region_id' => $item['region_id'], 'region_name' => $item['region_name'] ]; } // 累加营收 $monthGroups[$monthNo]['revenue_generated'] += $item['revenue_generated']; // 拆分当前item的engagementsArr,合并到唯一数组中 $currentEngagements = explode(',', $item['engagementsArr']); foreach ($currentEngagements as $engId) { $engId = trim($engId); if ($engId !== '') { $monthGroups[$monthNo]['engagements'][$engId] = true; // 利用键唯一性去重 } } } // 处理每个月份分组的最终数据:转换engagements为逗号分隔字符串,统计数量 $processedRegion = []; foreach ($monthGroups as $group) { $uniqueEngIds = array_keys($group['engagements']); $processedRegion[] = [ 'revenue_generated' => round($group['revenue_generated'], 2), // 保留两位小数匹配示例 'month_no' => $group['month_no'], 'engagements' => count($uniqueEngIds), 'engagementsArr' => implode(',', $uniqueEngIds), 'region_code' => $group['region_code'], 'region_id' => $group['region_id'], 'region_name' => $group['region_name'] ]; } $processedData[$regionKey] = $processedRegion; } return $processedData; } // 示例调用(假设$result是你的原始数组) // $result = [/* 原始数组内容 */]; // $output = processSalesData($result); // print_r($output); ?>
代码说明
- 分组逻辑:先按外层数组的区域键分组,再在每个区域内按
month_no分组处理数据 - 营收累加:直接对每个分组内的
revenue_generated进行累加 - 去重处理:用关联数组存储engagement ID,利用键的唯一性自动去重,避免重复统计
- 格式整理:最后将唯一的engagement ID数组转换为逗号分隔字符串,统计数量,并保留指定的区域字段
- 精度处理:对营收结果保留两位小数,与示例输出格式一致
内容的提问来源于stack exchange,提问作者S. M. Mahfuzur Rahman
相关产品推荐
相关产品推荐

