Over the years there have been multiple answers to this question, evolving from some clunky code.
In 2022 is there a one liner or improved way to get the condition that failed in a multiple if scenario?
example one, myVarTwo fails
if (( myVarOne == "alpha") && ( myVarTwo == "beta") && ( myVarThree == "cappa"){
// do stuff
}else{
console.log("failed at ...)
}
example two, myVarThree fails
if (( myVarOne == "alpha") && (( myVarTwo == "beta") || ( myVarThree == "cappa")){
// do stuff
}else{
console.log("failed at ...)
}
I am assuming the conditions test stops at the first fail.
Firstly, your assumption that the condition test stops at the first fail is correct. The logical && operator is a short-circuit operator. It will return at the first instance of a falsy evaluation. Conversely, the || opearator returns at the first instance of a truthy evaluation.
With that said, my only guess would be to use ternary operators but I'm not sure if you would consider it to be a one liner. Especially if you have a lot more conditions to check for, the ternary operator would get really really long and not very readable. The ternary operators can be seen as simulating multiple if...else conditions being tested sequentially, with an action for each check.
const myVarOne = "alpha",
myVarTwo = "notBeta",
myVarThree = "cappa"
const printFailure = (string) => {
console.log(`Failed at ${string}`)
}
const printSuccess = () => {
console.log('All conditions satisfied!')
}
// Method 1
myVarOne != "alpha" ? printFailure("myVarOne") : myVarTwo != "beta" ? printFailure("myVarTwo") : myVarThree != "cappa" ? printFailure("myVarThree") : printSuccess()
// Method 2
myVarOne == "alpha" ? myVarTwo == "beta" ? myVarThree == "cappa" ? printSuccess() : printFailure("myVarThree") : printFailure("myVarTwo") : printFailure("myVarOne")
Related
I want to write an if/else statement that tests if the value of a text input does NOT equal either one of two different values. Like this (excuse my pseudo-English code):
var test = $("#test").val();
if (test does not equal A or B){
do stuff;
}
else {
do other stuff;
}
How do I write the condition for the if statement on line 2?
Think of ! (negation operator) as "not", || (boolean-or operator) as "or" and && (boolean-and operator) as "and". See Operators and Operator Precedence.
Thus:
if(!(a || b)) {
// means neither a nor b
}
However, using De Morgan's Law, it could be written as:
if(!a && !b) {
// is not a and is not b
}
a and b above can be any expression (such as test == 'B' or whatever it needs to be).
Once again, if test == 'A' and test == 'B', are the expressions, note the expansion of the 1st form:
// if(!(a || b))
if(!((test == 'A') || (test == 'B')))
// or more simply, removing the inner parenthesis as
// || and && have a lower precedence than comparison and negation operators
if(!(test == 'A' || test == 'B'))
// and using DeMorgan's, we can turn this into
// this is the same as substituting into if(!a && !b)
if(!(test == 'A') && !(test == 'B'))
// and this can be simplified as !(x == y) is the same as (x != y)
if(test != 'A' && test != 'B')
ECMA2016 answer, especially good when checking against multiple values:
if (!["A","B", ...].includes(test)) {}
In general it would be something like this:
if(test != "A" && test != "B")
You should probably read up on JavaScript logical operators.
I do that using jQuery
if ( 0 > $.inArray( test, [a,b] ) ) { ... }
For a larger number of values that is checked against often, it may be more efficient to check if the value does not exist in a Set.
const values = new Set(["a", "b"]);
if(!values.has(someValue)){
// do something
} else {
// do something else
}
var test = $("#test").val();
if (test != 'A' && test != 'B'){
do stuff;
}
else {
do other stuff;
}
You used the word "or" in your pseudo code, but based on your first sentence, I think you mean and. There was some confusion about this because that is not how people usually speak.
You want:
var test = $("#test").val();
if (test !== 'A' && test !== 'B'){
do stuff;
}
else {
do other stuff;
}
This can be done with a switch statement as well. The order of the conditional is reversed but this really doesn't make a difference (and it's slightly simpler anyways).
switch(test) {
case A:
case B:
do other stuff;
break;
default:
do stuff;
}
Using the traditional if statement I can do this:
if(a===0 || b===0) {console.log('aloha amigo')};
But when I try to do something the same thing with a ternary operator, like this:
a===0 || b===0 && console.log('aloha amigo')
I just get errors about unexpected ||.
According to this answer: Precedence: Logical or vs. Ternary operator, we can do it using
condition1 || condition2 ? do if true : do if false
(Sorry I'm not sure how to call the ? : symbols in this case), but I'm not sure how to get it running using && (It means only run the code if returned true).
I created a codepen to test it easily. Here's the whole code:
var a = 0;
var b = 1;
a===0 || b===0 ? console.log('Works here') : console.log('And here');
a===0 || b===0 && console.log('Doesn\'t work here');
a===0 && console.log('The && works for a single test');
Here's the link
Just take parenthesis to prevent operator precedence of && over ||
(a === 0 || b === 0) && console.log('aloha amigo')
Without parenthesis, you get (now with to show the precedence) a different result.
a === 0 || (b === 0 && console.log('aloha amigo'))
^^^^^^^ first evaluation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second evaluation
var hungry = true;
var foodHere = true;
var eat = function() {
if (hungry && foodHere === true) {
return(true);
} else {
return(false);
}`
};
The first line is the correct syntax. For a long time I was just saying hungry && foodHere = true... and I couldn't figure out (and still don't understand) why that is wrong. I understand the difference between = (assignment) and === (equal to). I assigned the variables to be true initially, so aren't I asking in the if statement if that's what they're set to? Why am I setting the variables = to in the var definition, but then when checking them I'm using the === value?
= is only used to assign variables. === or == are used to compare. For a good example, we must look into comparison operators.
Syntax
The syntax of comparison operators is fairly simple, use them to evaluate expressions. The comparasin operators are:
=== //strict equality
== //Parsed or partial equality
> //Greater Than
< //Less than
>= //Greater than or equal to
<= //Less than or equal to
To properly use these, you must know the proper syntax. For example, I can't do something like:
if(true == 1 === true) //do something
as that would invalidate the code, and slow it down by much using ==, which brings me to my next section.
Equality
The two equality operators in JavaScript are == and ===. They do two very different things.
===
The strict equality (===) tests whether two values are exactly equivalent, both in type and value.
==
The Parsed equality (==) tests whether two values are equalivent in value, but parses to try and connect different types.
Inequality
There are 2 main inequality value in JavaScript (!==) they are pretty self explainatory based on the equalities (===, and ==)
here's a chart explaining the three.
1 0 true false null undefined ""
1 === !== == !== !== !== !==
0 !== === !== == == == !==
true == !== === !== !== !== !==
false !== == !== === == == ==
null !== == !== == == == ==
undefined !== == !== == == === !==
"" !== == !== == == !== ===
Adding onto what #jcollum said, = defines a variable value, and if(something === true) simplifies into if(something). Similarly, if(something === false) simplifies into if(!something).
You also need to do comparisons separately. if(7 & 6 < 10) returns false because it is the simplified version of if(7 === true && 6 < 10).
It turns:
hungry && foodHere === true
into
hungry && true
or just
hungry
Using the assignment operator instead of the comparison operator is stopping your logic from working correctly.
I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators
The law of non-contradiction dictates that two contradictory statements cannot both be true at the same time. That means that the expressions
(a && !a)
(a == !a)
(a === !a)
should always evaluate to a falsy value, and
(a || !a)
should always evaluate to a truthy value.
Fortunately, though, Javascript is a fun language that allows you to do all sorts of sick things. I bet someone a small fortune that it's possible to convince Javascript to break the law of non-contradiction, or, at least, convincingly make it look like it's breaking the law of non-contradiction. Now I'm trying to make all four of the above code examples give the unexpected result.
What would be a good way to go about this?
The best I can do is:
[] == ![] // true
or
var a = [];
a == !a
Of course this is really doing [] == false // true and !![] == ![] // false. It's really just a technicality.
EDIT: This is really a joke, but does work:
var a = false; var b = function() { return a = !a };
console.log(!!(b() && !b())); // true
console.log(b() == !b()); // true
console.log(b() === !b()); // true
console.log(b() || !b()); // true
This one will do the trick:
var a = '0';
a == !a
(evaluates to true)
In this case, a == false and !a == false.
a=NaN;
var a=NaN,
A=[(a && !a), (a == !a),(a === !a),(a || !a)];
alert(A)
/* returned value: (Array)
NaN,false,false,true
*/
I still haven't found anything to break && and ===, but here's one for == and ||:
Object.prototype.toString = function() {
return false;
};
a = {};
b = (a || !a);
alert(a || !a); //alerts false
alert(b == !b); //alerts true