Элегантный способ получить минимум между двумя ценами, выбрасывая неположительные значения

В настоящее время я делаю это в несколько этапов, и мне интересно, есть ли лучший способ.

Вот как я это делаю.

  1. Проверьте, не являются ли значения не числовыми или неположительными числами. Если они есть, выдать ошибку и выйти. Это гарантирует как минимум 1 положительное число.
  2. Приведите оба значения к (float), Если один из двух был не числовым, он должен быть 0 сейчас.
  3. Если num1 равен нулю, используйте num2. Иначе, если num2 равен нулю, используйте num1. Остальное использовать 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; это заставит нечисловые 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
}

демонстрация

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]