Currently, I'm doing this in several steps, and I wonder if there's a better way.
Here's how I'm doing it.
(float)
. If one of the two was non-numeric, it should be 0 now.min(num1,num2)
// 1
if(!(is_numeric($num1) && $num1 >0) && !(is_numeric($num2) && $num2 >0) ) {
die('error');
}
// at least one is a positive number. Other could be a different number or not numeric.
// 2
$num1 = (float)$num1;
$num2 = (float)$num2;
// now both are numbers, at least one is positive
// 3
if($num1 <= 0) {
$price = $num2;
} elseif($num2 <= 0) {
$price = $num1;
} else {
$price = min($num1,$num2);
}
// finally we have the price
I am using php5
I recommend that you convert the numbers to floats before comparing them to 0
; this will force non-numerics to 0
and then you can filter out the negatives, the original zeros, and the converted zeros in one step. If there are no qualifying prices, make an early return. If at least one qualifying price exists, return the lower of the two.
As a matter of convenient, simplified, DRY programming, I am batching the values into an array for swift handling.
Code: (Demo)
function newGetMinPrice($nums) {
$nums = array_filter($nums, function($v){ return (float)$v > 0;}); // convert to float and check if greater than 0
if (empty($nums)) {
return 'error'; // if no qualifying prices, return error
}
return min($nums); // return the lowest qualifying price
}
$tests = [[0, .1], [1, 'foo'], [.24, -.25], [3, 3], ['foo', 'bar'], [-0, 0.1], [90, -90], [0, 0], [1, 1]];
foreach ($tests as $test) {
echo "new: {$test[0]} -vs- {$test[1]} = ",newGetMinPrice($test), "
";
}
Output: (identical performance as your posted snippet
new: 0 -vs- 0.1 = 0.1
new: 1 -vs- foo = 1
new: 0.24 -vs- -0.25 = 0.24
new: 3 -vs- 3 = 3
new: foo -vs- bar = error
new: 0 -vs- 0.1 = 0.1
new: 90 -vs- -90 = 90
new: 0 -vs- 0 = error
new: 1 -vs- 1 = 1
...or you could condense like:
$nums = array_filter($nums, function($v){ return (float)$v > 0;}); // convert to float and check if greater than 0
return empty($nums) ? 'error' : min($nums);
p.s. you could also generate a battery of conditions if you don't want to use array_filter()
...though I don't think it is any prettier than your original snippet.
$num1 = max(0, (float)$num1);
$num2 = max(0, (float)$num2);
if ($num1 === 0) { // bad num1
if ($num2 === 0) { // bad num2
return 'error'; // send error
}
return $num2; // send good num2
}
// 1 is good...
if ($num2 === 0 || $num1 <= $num2) { // bad num2 or num1 better than num2
return $num1; // send good/better num1
}
return $num2; // both num1 and num2 are good, send num2
or without declaring newGetMinPrice()
:
$nums = array((float)$num1,(float)$num2); // force input values to float values
$nums = array_filter($nums, function($v){return $v > 0;}); // check if greater than 0
if (empty($nums)) {
die('error');
} else {
$price = min($nums); // declare lowest qualifying price
}