Что такое сокращенный способ проверки того, что несколько переменных ВСЕ равны одному значению в выражении IF? (PHP)
Есть ли сокращенный способ написания кода ниже?
if (($tstat=='no_prices')&&($l1stat=='no_prices')&&($l2stat=='no_prices')&&($l3stat=='no_prices'))
{
//do something
}
Я попытался использовать приведенный ниже код, но он сделал что-то, когда одна из переменных не была равна "no_prices".
if (($tstat && $l1stat && $l2stat && $l3stat)=='no_prices')
{
//do something
}
Чтобы проверить, что строки не вызывают проблем, я попытался заменить 0 на "no_prices" и 1 на другие значения, но результат был одинаков.
Ответы
Ответ 1
array_flip
в несколько раз быстрее array_unique
:
function all_equal($arr, $value) {
return array_keys(array_flip($arr)) == array($value);
}
$arr = array($tstat, $l1stat, $l2stat, $l3stat);
echo all_equal($arr, 'no_prices');
Быстрый профиль для ответов, предоставленных до сих пор, для 1000 итераций по длине массива 1000:
array_flip: 0.07321620 seconds
array_unique: 0.32569408 seconds
foreach: 0.15136194 seconds
array_filter: 0.41404295 seconds
Код, используемый для профиля, находится здесь: http://codepad.org/szgNfWHe
Примечание. Поскольку @cypherabe справедливо указывает на, array_flip
не обгоняет array_unique
, пока массив не будет иметь как минимум 5 элементов, и не обгоняет foreach
, пока массив не будет содержать как минимум 10 элементов.
Ответ 2
Если я не ошибаюсь, там нет собственного способа сделать это. Если это то, что вам нужно часто проверять, попробуйте использовать для него настраиваемую функцию, например:
function allEquals($chkstr, $vals) {
if (!is_array($vals)) { die('allEquals() $vals not an array'); }
foreach ($vals AS $v) {
if ($chkstr != $v) { return false; }
}
return true;
}
Ответ 3
Моя первая идея войдет в API PHP Array:
// $tstadt, $l1stat, … are all "no_prices"
$isAllNoPrice = array_unique(array($tstat, $l1stat, …)) == array("no_prices"));
if ($isAllNoPrice) {
// …
}
Документация обязательна, иначе никто (включая себя) не поймет код.
Если эффективность может быть проблемой, другие указали, что array_unique()
кажется медленным. Использование ключей хэш-таблицы будет следующим подходом:
// $tstadt, $l1stat, … are all "no_prices"
$varsMap = array(
$tstat => null,
$l1stat => null,
// …
);
if (array_keys($varsMap) == array("no_prices")) {
// …
}
Но теперь стена кода растет. PHP предлагает один оператор, который почти делает то, что вы хотите, и его можно связать: &
$v1 = "no_prices";
$v2 = "no_prices";
$v3 = "no_prices";
var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(true)
$v3 = "prices";
var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(false)
Я сказал, что он почти делает то, что вы хотите: Есть случаи, когда вы будете иметь ложные срабатывания:
$v1 = 1;
$v2 = 1;
$v3 = 3;
var_dump(($v1 & $v2 & $v3) == 1); // bool(true)
Для строк, кажется, вырезается битовая маска для кратчайшей строки:
$v1 = "abcd";
$v2 = "ab";
$v3 = "abc";
var_dump($v1 & $v2 & $v3); // "ab"
var_dump(($v1 & $v2 & $v3) == "ab"); // bool(true)
Поэтому я не рекомендую это как решение общего назначения. Только если вы знаете (= unit testing), что ваши значения находятся в наборе, где никакая комбинация никогда не приводит к ложному положительному (например, { "собака", "кошка", "лошадь" }), вы можете рассмотреть это решение. Я подумал об этом и должен сказать, что не использую это вообще. Представьте, как ваши коллеги будут любить вас для поиска ошибки, введенной этим методом.
Ответ 4
В вашем случае вы можете сделать:
if (count(array_unique($tstat, $l1stat, $l2stat, $l3stat)) == 1 //Check if all share the same value (i.e., number of unique values is 1
&& $tstat == 'no_prices')) //If everything is the same and $stat == 'no_prices', then everything is 'no_prices'
{
}
Ответ 5
<?php
$tstat = $l1stat = $l2stat = $l3stat = 'no_prices';
$testVars = array($tstat,$l1stat,$l2stat,$l3stat);
if(count(array_filter($testVars, function($x) { return $x === 'no_prices'; })) == count($testVars))
{
print("Correct");
}
Использовать array_filter с анонимным обратным вызовом и проверить, больше ли его длина, равна исходному массиву, то есть все условия, переданные,
или если длина больше нуля, то есть любое одно условие, прошедшее
Ответ 6
Нет, этот код не будет работать:
if (($tstat&&$l1stat&&$l2stat&&$l3stat)=='no_prices')
{
//do something
}
Почему? Потому что условие в круглых скобках проверяет результат сам - вы сравниваете логическое значение с строкой. Итак, в псевдокоде, вот как выглядит ваш код:
if ( ($tstat is true, $l1stat is true, $l2stat is true, $l3stat is true) == 'no_prices' )
^ whole thing returns true ^ ^ true ^
Если вы этого не сделаете, вы можете использовать count()
и array_unique()
:
if ($tstat == 'no_prices' && count(array_unique(array($tstat, $l1stat, $l2stat, $l3stat))) == 1)
Ответ 7
попробуйте следующее:
$arr = array($tstat,$l1stat,...); //make an array
$arr =array_unique($arr);//unique this array
if(count($arr) == 1 && $arr[0] = 'no_prices'){ // check if only one array element have with same value
echo "got it";
}
Ответ 8
Ответ "нет". Там нет стенограммы для данного условия, которое сделает ваш код более читаемым, что должно быть вашим главным приоритетом. Вы можете улучшить его, хотя:
define('MYAPP_NO_PRICES', 'no_prices');
if ($tstat === MYAPP_NO_PRICES
&& $l1stat === MYAPP_NO_PRICES
&& $l2stat === MYAPP_NO_PRICES
&& $l3stat === MYAPP_NO_PRICES) {
// do something
}
Наличие всех этих варов для проверки индивидуально - это запах кода; вы можете захотеть переосмыслить этот дизайн, чтобы вам никогда не приходилось это делать.