如何优雅获取两个价格的最小值并排除非正值?求更优实现方案
优化你的数值筛选逻辑
看起来你已经实现了一个从两个值里筛选有效正数的逻辑,不过确实可以简化得更优雅一些,我来帮你梳理下优化思路和方案~
你的现有实现逻辑
先帮你把现有步骤和代码整理清楚:
- 校验两个值是否均为非数值或均为非正数,如果是就抛出错误退出,确保至少有一个有效正数
- 将两个值强制转为
(float)类型,非数值转换后会变成0 - 分支判断选择结果:
- 若
num1为0,就用num2 - 若
num2为0,就用num1 - 两个都不为0时取最小值
- 若
对应的代码片段(补全截断部分):
// 1. 校验至少有一个有效正数 if (!(is_numeric($num1) && $num1 > 0) && !(is_numeric($num2) && $num2 > 0)) { throw new Exception("至少需要一个正数"); exit; } // 2. 转换为float,非数值转为0 $num1 = (float)$num1; $num2 = (float)$num2; // 3. 选择目标值 if ($num1 == 0) { $result = $num2; } elseif ($num2 == 0) { $result = $num1; } else { $result = min($num1, $num2); }
更简洁的优化实现
我们可以把校验、转换和筛选逻辑合并,减少冗余判断,同时让代码逻辑更直观:
核心优化思路
- 先把两个值处理成有效正数集合:直接过滤掉非数值、≤0的无效值,只保留合法的正数
- 检查这个集合是否为空,为空则抛出错误(和原逻辑的校验要求一致)
- 直接取集合中的最小值(因为集合里至少有一个元素,
min()函数可以直接生效)
优化后代码
// 处理两个值,筛选出有效正数(非数值转float后为0,会被过滤) $validNumbers = array_filter( [(float)$num1, (float)$num2], function($val) { return $val > 0; } ); // 校验至少有一个有效正数 if (empty($validNumbers)) { throw new Exception("至少需要一个正数"); exit; } // 直接取有效正数中的最小值 $result = min($validNumbers);
优化点说明
- 减少冗余分支:不用单独判断哪个值是0,
array_filter已经帮我们把所有无效值(包括非数值转成的0)都排除了 - 逻辑更直观:代码直接体现“保留有效正数,选最小的”核心需求,可读性更强
- 扩展性更好:如果以后需要处理3个甚至更多值,只需要在数组里添加元素即可,不需要修改后续的判断逻辑
可选的严谨版(区分非数值和非正数)
如果你的需求里需要严格排除非数值(而不是转成0再过滤),可以调整过滤逻辑,先判断是否为数值再转成正数:
// 先筛选出数值类型且大于0的值 $validNumbers = array_filter( [$num1, $num2], function($val) { return is_numeric($val) && (float)$val > 0; } ); // 把剩下的有效值转为float类型 $validNumbers = array_map('floatval', $validNumbers); // 校验逻辑不变 if (empty($validNumbers)) { throw new Exception("至少需要一个正数"); exit; } $result = min($validNumbers);
这个版本会先排除所有非数值的元素,再处理有效数值,逻辑更严谨,适合对输入类型要求更高的场景。
内容的提问来源于stack exchange,提问作者Buttle Butkus
相关产品推荐
相关产品推荐

