How to combine different conditions in JavaScript? - javascript

So I m building one game which is drenching the field according to selected colour and I have 4 different conditions:
let condition1 = drenchX + 1 === mixedX && drenchY === mixedY && this.mixedFields[i].style.backgroundColor === this.service.clickedColor;
let condition2 = drenchX === mixedX && drenchY + 1 === mixedY && this.mixedFields[i].style.backgroundColor === this.service.clickedColor;
let condition3 = drenchX - 1 === mixedX && drenchY === mixedY && this.mixedFields[i].style.backgroundColor === this.service.clickedColor;
let condition4 = drenchX === mixedX && drenchY - 1 === mixedY && this.mixedFields[i].style.backgroundColor === this.service.clickedColor;
I need to get all possible combinations of this conditions, all 4 of them can be true, or 3 or 2 or just one.
This works fine but I think it is too long.
My if statement looks like this:
if((condition1 && condition2 && condition3 && condition4) || (condition1 && condition2 && condition3) || (condition1 && condition2 && condition4) || (condition1 && condition3 && condition4) || (condition2 && condition3 && condition4) || (condition1 && condition2) || (condition1 && condition3) || (condition1 && condition4) || (condition2 && condition3) || (condition2 && condition4) || (condition3 && condition4) || condition1 || condition2 || condition3 || condition4) {
// some action
}
It all works perfectly but I m looking for a shorter solution and I m still a beginner in this. So if anyone know a better way to do this that would be great, my statement is just too long and it doesn't looks good at all.
Btw, project is in Angular. Maybe to create some function for this?

If a && b is true, then a || b is also true. That said it means your condition can just be
if (condition1 || condition2 || condition3 || condition4)

If I understand correctly, the if-statement is checking whether any of the conditions are met. Therefore, this should do the trick:
if(condition1 ||
condition2 ||
condition3 ||
condition4)
{
//some action
}

Thanks everyone for advices, but I found a way to simplify it. I stored conditions into array and used for-in to loop thru all possible conditions.
let conditionalArray: boolean[] = [condition1, condition2, condition3, condition4];
for(let c in conditionalArray){
if(conditionalArray[c]) {
//....
}
}

Related

if statement with javascript condition operator

just have 2 question regarding JS conditional operator, is the below 2 expression valid?
1.
if(isUser && isUser === true || isGuest && isGuest === true){
//...
}
I am wondering do I have to add () to make it like and still have the same functioning:
if((isUser && isUser === true) || (isGuest && isGuest === true)){
//...
}
const items = list.orderList && list.orderList.isUser === true || list.orderList.isGuest ? list.items : [];
I am wondering do I have to add () to make it like and functioning the same as above conditional operator:
const items = list.orderList && (list.orderList.isUser === true || list.orderList.isGuest === true) ? list.items : [];
As per Operator Precedence in the MDN docs, logical AND takes precedence over logical OR. Therefore,
expression1 || expression2 && expression3
will evaluate to
expression1 || (expression2 && expression3)
Therefore,
isUser && isUser === true || isGuest && isGuest === true
naturally evaluates to
(isUser && isUser === true) || (isGuest && isGuest === true)
anyway, so you do not need parentheses..
But since, in your second example, you want to evaluate OR then AND, you do need parentheses for it to evaluate the way you require, as
list.orderList && list.orderList.isUser === true || list.orderList.isGuest
will evaluate to
(list.orderList && list.orderList.isUser === true) || list.orderList.isGuest

how can I turn two statements into a ternary

I have two if statements that'd like to turn into a ternary but I don't know how.
if (val === true && optval === 'car' || val === true && optval === 'truck' )view_list.style.display = 'none';
if (val === true && optval === 'buss' || val === true && optval === 'van')view_list.style.display = '';
Apart in hacks I won't mention, a ternary is used when you want to return a value in all cases.
If val isn't true, then you do nothing.
Therefore this can't be used here.
view_list.style.display =
(val === true && optval === 'car' ||
val === true && optval === 'truck' ) ?
'none' :
((val === true && optval === 'buss' ||
val === true && optval === 'van') ?
'' :
view_list.style.display ) ;
or more succinctly :
view_list.style.display =
(val === true && ( optval === 'car' || optval === 'truck' ) ) ?
'none' :
((val === true && ( optval === 'buss' || optval === 'van' ) ?
'' :
view_list.style.display );
The parentheses around the second conditional are optional.
Of course this is not really a good approach, and this answer should not be seen as an endorsement to this style of programming.
Because nobody has said it yet, switch
if (val === true)
switch (optval) {
case 'car':
case 'truck':
view_list.style.display = 'none';
break;
case 'buss':
case 'van':
view_list.style.display = '';
break;
}
Not what you were asking for, but as #dystroy said, this is not the best case for a ternary.
But you can still make it a bit more elegant. How about
var styleMapping = {
'car': 'none',
'truck': 'none',
'buss': '',
'van': ''
};
// Apparently val is always required in your example
if (val) {
view_list.style.display = styleMapping[optval];
}
This also has the benefit that refactoring and adding new styles is very easy without having to write much code. Just add one line in the mapping and you're done. And of course it's much more readable and closer to what you intend to do.
You don't really care about boolean logic, you just want to have a different style based on what optval is set to.

Location.pathname.indexOf not working with 'Or' ( || )

I'm trying to use location.pathname.indexOf to make conditional jQuery work on some pages on my site.
This works:
if (location.pathname.indexOf("/example/5820.htm") != 0){}
This works:
if (location.pathname.indexOf("/example-1/3569.htm") != 0) {}
This doesn't work:
if (location.pathname.indexOf("/example/5820.htm") != 0 || location.pathname.indexOf("/example-1/3569.htm") != 0) {}
I've done this a ton of times and for some reason this code is not working. I'm wondering if I'm missing something little in the code or if it's something else?
Tim already answered this question, but don't forget:
.indexOf() will return -1 when the string isn't found, not 0.
if (location.pathname.indexOf("/example/5820.htm") != 0){}
Should be:
if (location.pathname.indexOf("/example/5820.htm") != -1){}
Or:
if (location.pathname.indexOf("/example/5820.htm") >= 0){}
http://www.w3schools.com/jsref/jsref_indexof.asp
basically you're saying this:
var a = 0;
var b = 1;
if (a != 0 || b != 0) {};
Which is equal to
if (!(a == 0 && b == 0)) {};
However, you actually want this:
if (!(a == 0 || b == 0)) {};
Which is equal to:
if (a != 0 && b != 0) {};

Which Logic Operator Takes Precedence

So, I'm looking into writing a slightly more complex operation with logic operators in an if-else statement. I know I can do parentheses, and I know it's the better way of doing this, but I've gotten curious and so I'm going to ask. If I were to do something like this:
if (firstRun == true || selectedCategory != undefined && selectedState != undefined) {
//Do something
} else {
//Do something else
}
How will that be operated without the use of parentheses? I know there is an order of operations for logic operators, similar to PEMDAS, right? I'm curious if it'll be ran something like this:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
or maybe if the 'OR' operator takes precedence instead and it ends up going like:
(firstRun == true || selectedCategory != undefined) && selectedState != undefined
The full list would be nice, if you can find it somewhere, of the order of operations for this. Thanks!
My rule of thumb, which covers basically 99% of all use cases for conditional statements, is:
Grouping: ()
Member access . or [...]
Not: !
Comparison, e.g. < , >= , === , !=, ...
Logical AND &&
Logical OR ||
MDN gives you the exhaustive breakdown: JavaScript Operator Precedence
So for your example:
(firstRun == true || selectedCategory != undefined && selectedState != undefined)
equals
(firstRun == true) || ((selectedCategory != undefined) && (selectedState != undefined))
For anything more complex than the above mentioned cases, I would look into refactoring the code for readability's sake anyway!
There is a pretty good rule of thumb to this. Think of these operators as of mathematical ones:
AND is multiplication (eg. 0 * 1 = 0 => FALSE)
OR is adding (eg. 0 + 1 = 1 => TRUE)
When you remember this, all you have to know is that multiplication always comes before addition.
See this chart for precedence.
I'm not going to explain what happens because the next guy reading your code will think: "WTF? Does that do what it should?"
So the better solution is to wrap the terms in parentheses even if you know the precedence, applied it correctly and the code works
This follows the old wisdom that you shouldn't do everything you can just because you can do it. Always keep an eye on the consequences.
See Operator precedence.
&& is before ||, so your expression is equivalent to:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
It will be the first:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
As a general rule, in most programming languages, AND has higher precedence.
While logical operator precedence is not actually defined in the ECMAScript Specification, MDN does a pretty good job of it and even has a separate page for logical operators.
My concern I suppose, since logical operator precedence is not actually defined in the ECMAScript specification, each individual browser vendor can potentially be different (I'm talking to you, Internet Explorer!), so your mileage may vary.
In the event anyone wants to test this across different browsers, here's a test case fiddle: http://jsfiddle.net/HdzXq/
$(document).ready(function() {
function log(test) {
$('div#out').append($('<p />').text(test));
}
function testOperatorPrecedence() {
log('(false || false && false) === ' + (false || false && false).toString());
log('(false || false && true) === ' + (false || false && true).toString());
log('(false || true && false) === ' + (false || true && false).toString());
log('(false || true && true) === ' + (false || true && true).toString());
log('(true || false && false) === ' + (true || false && false).toString());
log('(true || false && true) === ' + (true || false && true).toString());
log('(true || true && false) === ' + (true || true && false).toString());
log('(true || true && true) === ' + (true || true && true).toString());
log('----------------------------');
log('(false || (false && false)) === ' + (false || (false && false)).toString());
log('(false || (false && true )) === ' + (false || (false && true)).toString());
log('(false || (true && false)) === ' + (false || (true && false)).toString());
log('(false || (true && true )) === ' + (false || (true && true)).toString());
log('(true || (false && false)) === ' + (true || (false && false)).toString());
log('(true || (false && true )) === ' + (true || (false && true)).toString());
log('(true || (true && false)) === ' + (true || (true && false)).toString());
log('(true || (true && true )) === ' + (true || (true && true)).toString());
}
testOperatorPrecedence();
});

What is the correct syntax for this 'OR' and 'AND' in this 'IF' statement?

I've got an 'if' statement and just wanted to know if these are both valid (which I believe they are) and if so what is the difference?
var type;
var type2;
if ((type == 'BOS'|| type == 'BPS'|| type == 'BRS') && (type2 == 'BOS'|| type2 == 'BPS'|| type2 == 'BRS))
OR
if ((type == 'BOS') || (type == 'BPS') || (type == 'BRS') && (type2 == 'BOS') || (type2 == 'BPS') || (type2 == 'BRS'))
Which has the correct syntax and do they do anything differently? is there a way to shorten this statement?
Thanks
The two statements are different. Yes, they are both valid statements, syntactically, but logically they differ. Since the && operator has a higher precedence than the || in javscript,
the resulting logic will evaluate as follows in statement 2:
1) (type == 'BRS') && (type2 == 'BOS')
2) (type == 'BOS') || (type == 'BPS') || (result of 1) || (type2 == 'BPS') || (type2 == 'BRS')
While in statement 1:
1) (type == 'BOS'|| type == 'BPS'|| type == 'BRS')
2) (type2 == 'BOS'|| type2 == 'BPS'|| type2 == 'BRS')
3) (result of 1) && (result of 2)
var type1;
var type2;
var correct_value = {
BRS: 1,
BOS: 1,
BPS: 1
};
if( correct_value[type1] && correct_value[type2]) {
alert('ok');
}
else {
alert('not ok');
}
Both conditional statement are valid but the result may be different.
The first statement will evaluate the OR value in the first bracket, and then evaluate the OR value in the second bracket, and finally evaluate the AND operator.
The second statement will evaluate the AND first and then evaluate from left to right without specific precedence (as in the first one).
You have to know which one do you actually use to determine the best refactoring code for it.
See this link: Operator Precedence.

Categories