2013-12-06 3 views
2

Предположим, что у нас есть эти шесть переменных: a,b,c,x,y,z. Есть ли лучший способ написать это утверждение if, которое не так сильно читается?DRY - как заменить этот if-оператор на менее сложный

if (((!a && !x) || a === x) && ((!b && !y) || b === y) && ((!c && !z) || c === z)) 

Теперь пусть эти переменные будут намного длиннее, и этот код будет более сложным и менее читаемым.

+1

'! A &&! B <=>! (A || b)', если это упростит. Мне всегда легче иметь как можно меньше отрицаний в моих структурах управления. – Christoph

+0

@Christoph благодарит за совет –

ответ

3

Расширение функционального подхода. Функция сравнения может использоваться как метод every() для внутреннего вызова обратного вызова. Чтобы не передавать массив в качестве аргумента функции, я буду использовать call() на arguments.

function compare() { 
    return Array.prototype.every.call(arguments, function (e) { 
    return !e[0] && !e[1] || e[0] === e[1]; 
    }); 
} 

if (compare([a, x], [b, y], [c, z])) { 
    // Do something 
} 
+0

+1, очень хороший подход.) Опять же, описательное имя не повредит. – raina77ow

+2

Вам не нужно создавать новый массив, вы можете просто вызвать 'Array.prototype.every.call (arguments, function ...)' – Tibos

+0

, что ответ кажется более универсальным, поэтому я принимаю его как лучший (и, конечно, голосование) –

5

Один очевидный подход заключается в functionize код, который повторяется:

function checkVars(a, b) { 
    return !a && !b || a === b; 
} 

// ... 
if (checkVars(a, x) && checkVars(b, y) && checkVars (c, z)) { 
// ... 
} 

Как совершенно правильно сказано, вы должны дать эту функцию описательное имя, показывая, что он действительно делает. По-видимому, он проверяет, являются ли заданные переменные ложными или идентичны ли они, поэтому один очевидный выбор - falsyOrIdentical. Тогда ваше if заявления станет действительно самостоятельное комментирование:

if (falsyOrIdentical(a, x) 
&& falsyOrIdentical(b, y) 
&& falsyOrIdentical(c, z)) { 

// here goes the code 
} 

Если есть больше переменных, чтобы проверить, подход Павло (в одной функции, используя slice.call(arguments) трюк, чтобы превратить весь ВАР в массив, а затем применять эту функцию до тех пор, пока не удается для каждого элемента этого массива с помощью метода every) является лучшим. Но опять же, я действительно задаюсь вопросом, не должны ли все эти переменные быть частью коллекции - так что вы сможете сразу перейти с every.

+3

Не забудьте назвать функцию чем-то описательным, если это возможно. – wei2912

+0

и что, если у меня есть более 6 переменных? Есть ли возможность не писать, т. Е. 10 раз «falsyOrIdentical»? –

+0

Ну, это настоятельно предполагает, что вы должны фактически работать с коллекцией (Array или Object), а не только с кучей переменных. В этом случае Array.every выглядит очень простое решение для этой работы. – raina77ow

0

Вы должны использовать логические переменные для упрощения сравнения.

Пример:!
а & & х может быть преобразована в нечто вроде

var aAndBeIsNotTrue = !a && !x 
var bAndYIsNotTrue = !b && !y 

И если заявление будет выглядеть

if(aAndBIsNotTrue || a === x) && (bAndYIsNotTrue || b === y) 

Я думаю, вы получите точку. Вы также можете использовать отличные новые методы с читаемыми именами и поместить логическую логику в эти методы. Они также могут быть хорошо протестированы.

В книге «Чистый код» содержатся интересные примеры использования логических переменных для упрощения сложных операторов if.

-1

Привет Мы можем использовать, если еще лестница, чтобы решить эту проблему: Здесь я использую функцию CheckCondition() с возвращаемым значением, как BOOL.

CheckCondition() 
    { 
if((!a&&!x)||a==x) 
{ 
if((!b&&!y)||b==y) 
{ 
if((!c&&!z)||c==z) 
{ 
return true; 
} 
else return false; 
} 
else return false; 
} 
else return false; 
} 

Условие if также может быть разбито на дальнейшую лестницу.

+1

и с 20 переменными эта функция займет 100 строк кода - это не СУХОЙ –

Смежные вопросы