В настоящее время я делаю это в несколько этапов, и мне интересно, есть ли лучший способ.
Вот как я это делаю.
(float)
, Если один из двух был не числовым, он должен быть 0 сейчас.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
Я использую php5
Я рекомендую вам преобразовать числа в числа с плавающей точкой, прежде чем сравнивать их с 0
; это заставит нечисловые 0
и затем вы можете отфильтровать негативы, исходные нули и преобразованные нули за один шаг. Если нет соответствующих цен, сделайте ранний возврат. Если существует хотя бы одна подходящая цена, верните нижнюю из двух.
В целях удобного, упрощенного, СУХОГО программирования я собираю значения в массив для быстрой обработки.
Код: (демонстрация)
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), "\n";
}
Вывод: (идентичная производительность как ваш опубликованный фрагмент
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
…или вы можете сжать как:
$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);
постскриптум Вы также можете создать батарею условий, если вы не хотите использовать array_filter()
… хотя я не думаю, что это красивее, чем ваш оригинальный фрагмент.
$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
или без объявления 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
}
Других решений пока нет …