PHP中按gear分组求和数组total、efforts、afh字段的问题
解决PHP数组按gear分组求和的问题
首先明确你的需求:把$estimate数组按gear字段分组,对每组的total、efforts、afh字段求和,生成新数组。先把你给出的原始数组整理成更易读的格式:
$estimate = [ ['gear' => 'MMG', 'total' => 315, 'efforts' => 9, 'afh' => 18], ['gear' => 'MMG', 'total' => 400, 'efforts' => 2, 'afh' => 6], ['gear' => 'BOO', 'total' => 200, 'efforts' => 20, 'afh' => 16], ['gear' => 'BOB', 'total' => 250, 'efforts' => 20, 'afh' => 16], ];
原代码的问题分析
你的代码用了嵌套循环+goto实现,但存在几个核心问题导致gear类别增多时失效:
- 索引逻辑混乱:你直接用原数组的索引
$et作为结果数组$calculate的索引,当原数组中同gear元素不连续、或新增gear类别时,$calculate的索引会出现跳变,后续循环判断极易出错。 goto滥用:goto让代码逻辑分支变得零散,一旦数组规模变大,很容易出现逻辑遗漏,调试起来非常困难。- 重复计算数组长度:嵌套循环中每次都调用
count($calculate),虽然PHP会做优化,但动态变化的数组长度可能导致循环边界异常。
稳定高效的实现方案
其实PHP处理这种分组求和非常简单,只需要一次遍历,用gear作为结果数组的键就能完成,完全不需要嵌套循环:
$calculate = []; foreach ($estimate as $item) { $gear = $item['gear']; // 若该gear已存在于结果数组,直接累加字段值 if (isset($calculate[$gear])) { $calculate[$gear]['total'] += $item['total']; $calculate[$gear]['efforts'] += $item['efforts']; $calculate[$gear]['afh'] += $item['afh']; } else { // 首次遇到该gear,初始化条目 $calculate[$gear] = [ 'gear' => $gear, 'total' => $item['total'], 'efforts' => $item['efforts'], 'afh' => $item['afh'], ]; } } // 若需要把结果数组转为连续数字索引,执行以下代码 $calculate = array_values($calculate);
代码说明
- 遍历原数组的每个元素,取出
gear作为分组标识; - 检查结果数组中是否已有该gear的条目:存在则累加字段值,不存在则初始化新条目;
- 最后用
array_values()可以将结果数组的键重置为连续数字索引,和你原代码的输出格式保持一致。
用你的示例数组测试,最终$calculate的结果为:
[ ['gear' => 'MMG', 'total' => 715, 'efforts' => 11, 'afh' => 24], ['gear' => 'BOO', 'total' => 200, 'efforts' => 20, 'afh' => 16], ['gear' => 'BOB', 'total' => 250, 'efforts' => 20, 'afh' => 16], ]
这个方案逻辑清晰,时间复杂度为O(n),不管原数组有多少个gear类别,都能稳定运行。
内容的提问来源于stack exchange,提问作者Mukhila Asokan
相关产品推荐
相关产品推荐

