PHP按指定顺序递减数组值时for循环未执行问题排查
问题原因
- for循环的进入条件写反:原代码循环判断条件为
array_sum($stapleArray) === $sizeDayArray,含义是仅当数组元素和等于目标值时才执行循环体。示例场景下初始数组和为6,目标值为4,条件从一开始就不成立,循环自然不会执行。 - 原循环逻辑存在设计缺陷:即使修正条件,逐次循环取模跳过0值元素的写法会产生大量无意义的循环判断,还可能因为元素值不足出现死循环;且每次循环都调用
array_sum计算总和,存在不必要的性能开销。 - 传入的
$substractionnumber参数本身就是需要扣减的总次数,原逻辑完全没有利用这个预计算值,逻辑冗余。
修复后的实现
按照noodle -> bread -> rice的优先级顺序扣减,优先扣减高优先级品类的数值,扣到0后再处理下一个品类,直到扣完所有需要扣减的额度即可:
private function substractStapleFood($substractionnumber, $stapleArray, $sizeDayArray) { // 按扣减优先级从高到低定义键顺序 $subtractOrder = ['noodle', 'bread', 'rice']; $remainingSubtract = $substractionnumber; foreach ($subtractOrder as $foodKey) { if ($remainingSubtract <= 0) { break; } // 单次最多扣减当前品类的现有值,避免扣成负数 $currentSubtract = min($stapleArray[$foodKey], $remainingSubtract); $stapleArray[$foodKey] -= $currentSubtract; $remainingSubtract -= $currentSubtract; } return $stapleArray; }
示例验证
代入提供的测试参数:
- 初始主食数组和为
5+0+1=6,目标天数为4,需扣减总次数为6-4=2 - 优先处理noodle:当前值为1,扣减1后noodle值为0,剩余待扣次数为1
- 其次处理bread:当前值为0,无额度可扣,直接跳过
- 最后处理rice:当前值为5,扣减剩余的1次后rice值为4,待扣次数清零,循环结束
- 最终返回结果为
[rice=>4, bread=>0, noodle=>0],完全符合预期。
内容的提问来源于stack exchange,提问作者Murata
相关产品推荐
相关产品推荐

