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;
}
Related
Is there an elegant way to check if variable is NOT falsy but in case of 0 it passes. The issue with this way of verifying
if(var !== undefined && var !== null)
is that it's long and doesn't cover all cases like undecalred or NaN. I'm also using typescript and declare it as optional number.
You can do exactly what your first sentence asks:
if (!x && x !== 0)
means literally "if x is falsy and x is not 0".
Also the == and != comparison operators explicitly consider null and undefined to be equal, so
if (x != null)
is true for both null and undefined. (That's !=, not !==.)
function Check(input) {
if (!input && input!==0){
return "falsy";
}
else if (input === 0){
return "zero";
}
}
console.log(Check(0));
console.log(Check(false))
var choice1 = prompt("Enter choice 1");
var choice2 = prompt("Enter choice 2");
if (choice1 === "x" && choice2 === ("a" || "b" || "c")) {
alert("Good job!");
}
Assume the user input x for choice1 and c for choice 2.
The above is a simple example to highlight my issue. I know it doesn't work but my question is why? Javascript won't compare the multiple || statements within () against choice2. Why not? The logic in my mind is choice2 is the same type and value (===) as "a" or "b" or "c".
The way I got it working was this:
(choice1 === "x" && ((choice2 === "a") || (choice2 === "b") || (choice3 === "c"));
Please help me understand why when using multiple ||'s, you need to explicitly write out each || scenario as opposed to putting a bunch within () as I tried up top. Thanks.
It just doesn't work that way, you can't compare one value against multiple other values using OR, you have to compare each value individually.
The closest you'll get is using Array.indexOf
if ( ['a', 'b', 'c'].indexOf(choice2) != -1 )
The reason it doesn't work is because OR and AND checks for a truthy value, so in
('a' || 'b' || 'c') // return "a"
a is a truthy value, so the OR never proceeds, it doesn't have to, it already has a truthy value so the expression is true, and you're left with a, the rest is discarded
In JavaScript, if you do this
var a = null;
var b = {};
var c = "haha"
var d = a || b || c;
the value of d will be b. Expressions of type var1 || var2 || var3 return with the value of first not null or not undefined value.
So, in you case choice2 === ("a" || "b" || "c") is same as writing choice2 === "a".
(object || object) syntax is something like null check operator not for condition check in javascript.
so
console.log(null || "b") would log b
console.log(undefined || "b") would log b
console.log(("a" || "b")) would log a
console.log(null || "b")
console.log(undefined || "b")
console.log(("a" || "b"))
Your condintion(below) will only work if choice2 is "a" and choice1 is "x".
if (choice1 === "x" && choice2 === ("a" || "b" || "c")) {
alert("Good job!");
}
What is in the brackets get evaluated first so ("a" || "b" || "c") will evaluate to "a" because what you are effectively saying is return either "a" or "b" or "c" so it returns "a" because that is first.
I believe what you are expecting is ("a" || "b" || "c") to act some sort of set operation but JavaScript doesn't have that feature so your code choice2 === ("a" || "b" || "c") will only ever be true if the user chose "a". The best way to compare multiple values with choice2 is to store "a","b" and "c" in an array and see if choice2 exists in it. ["a","b","c"].indexOf(choice2) != -1.
In most languages you won't even be able to compare three strings but JavaScript does everything it can to not throw exceptions so it doesn't cause the user of the website to realise there is a problem with the page so it will try and compare the three strings as you would compare three booleans but instead of returning a boolean it returns a string. I would avoid that syntax completely as it would confuse most developers not familiar with the weird ways of JavaScript.
Why does this fail?
The way I read this code is "if either a or b or c equals three, then the statement is true". But apparently JavaScript disagrees. Why?
function test() {
var a = 'one';
var b = 'two';
var c = 'three';
return ( ( a || b || c ) === 'three' );
}
EDIT: am aware of the fact that i need to evaluate each expression separately, but was looking for a quicker way to write it. any suggestions will be welcome.
Your reading of the code is incorrect. Translated to a different form:
if (a) {
return a === "three";
}
if (b) {
return b === "three";
}
if (c) {
return c === "three";
}
The subexpression (a || b || c) returns the first of a, b, or c that is not "falsy". That's a, because its value is "one", so that's the overall value that's compared to "three".
The expression ( a || b || c ) returns anything that is truthy on the first-come-first served basis.
Here a is truthy and hence used. If a is falsey b will be used. If it is falsey too, c will be used.
So, you always end up comparing "one" == "three" since strings are considered truthy. You can make use of Array.some in this case, which does what you want or how you want it to behave, in your words
"if either a or b or c equals three, then the statement is true"
return [a,b,c].some(function(str){
return str == "three";
});
This evaluates to is a, b, or c (which will be true or false) the string-equivalent of "three". Which will always be false.
In order to achieve what you want, you need
return (a === 'three') || (b === 'three') || (c === 'three');
I'm curious, is there a simpler way to say
if(myVar == myVal || myVar == myOtherVal){ /*...*/ }
such as:
if(myVar == myVal || myOtherVal){ /* */ }
I am aware that my proposed code only checkes to see whether myVar equals myVal or myOtherVal is not null (undefined) and false.
So, as I stated before, is there a simpler way to write
if(myVar == myVal || myVar == myOtherVal){ /*...*/ }
Just curious to know if there's some sort of jS shorthand if statment that works like this that I have missed.
Thanks in advance.
This should be what you are looking for. http://snook.ca/archives/javascript/testing_for_a_v
You could use arrays:
if([myVal, myOtherVal].indexOf(myVar) + 1) { /* or > -1 or !== -1 */ }
Or switch statements:
switch(myVar) {
case myVal:
case myOtherVal:
/* */
break;
}
These only really apply when comparing the variable to more than two possible values, though.
Not that I know of.
You could use the Array's indexOf with an array if you really wanted.
Another way is to use && as a "guard":
(myVar == myVal || myVar == myOtherVal) && /* expression */
But I don't recommend it. Your code should be easily read and maintained, so:
if (myVar == myVal || myVar == myOtherVal) {
/* do stuff */
}
is much better to me.
Ternary Operator:
result = ((myVar==myval)||(myVar==myOtherVal)) ? x : y;
Can be:
if((myVar==myVal) || (myVar==myOtherVal))
result = x;
else
result = y;
Also:
((myVar==myval)||(myVar==myOtherVal)) ? someFunction() : otherFunction();
Is the same as:
if((myVar==myVal) || (myVar==myOtherVal))
someFunction();
else
otherFunction();
var c = false;
if(c=[] && c.length==0)alert('hi');
hi is not alerted because c is still false when it executes the second operand of &&, can someone explain how the boolean operands in if condition are executed and in what order?
I believe this is just a precedence issue - && is binding tighter than =. Your code is equivalent to:
if (c = ([] && c.length == 0))
{
alert('hi');
}
So it's assigning c the value false rather than the empty array.
Try this instead:
if ((c = []) && c.length == 0)
{
alert('hi');
}
EDIT: To address Tryptich's comment - I did try this before posting :) As CMS said, an empty array is considered true. Try this:
if (c = [])
{
alert('empty array is true');
}
or even just this:
if ([])
{
alert('empty array is true');
}
I checked the spec before posting - I was somewhat surprised that an empty array is considered true, but it is...