My classmate used "||" instead of "&&" for an if statement, but the result is the same. I tried to understand the differences by reading the article but I can't seem to understand them. I would appreciate if anyone can explain in an easy way...Thank you!
&& is and operator and || is or operator
&& work as
1 && 1= 1
1 && 0 = 0
0 && 1 = 0
0 && 0 = 0
|| work as
1 || 1= 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
where 1 , 0 are true and false
we can understand it by the following example
suppose we have a code
if(1==1 && 2==2){}
so 1==1 is true means 1 and 2==2 is true means 1, so && operator work like this
1 && 1 =1 hence the result will be true and execute if statement
You could replace logical OR || with logical AND && and vice versa, by using De Morgan's laws:
!(a && b) = !a || !b
!(a || b) = !a && !b
If you have
if (a || b)
you could use this without OR
if (!(!a && !b))
Related
Is it possible to have conditions in return in JavaScript?
Like in this case:
if
(A > 0 || B > 0)
return "A";
else return "C"
As long as A or B is > 0 return the one that is > 0 (so A or B). Is that possible? Like another condition as return, for example?
Maybe this is similar to what you are trying to do. My function eval() takes two parameters A and B, and checks different conditions to see which is the positive number. I am using the Logical AND && instead of || because I want my code to know the value of each parameter in each condition.
function eval(A, B) {
if (A > 0 && B <= 0) {
return 'A';
}
if (A <= 0 && B > 0) {
return 'B';
}
if (A > 0 && B > 0) return "Both A and B are positive numbers";
}
console.log(eval(2, -5));
console.log(eval(0, 8));
console.log(eval(1, 1));
Try this.
return (A > 0 || B > 0) ? "A" : "C"
It's a ternary operator. Here you have more information:
Conditional (ternary) operator
if(A > 0 || B > 0)
return A > 0 ? "A" : "B";
else return "C";
I've thought I figured out how basic javascript logic works, but here I must have forgot something.
let firstElementSavedIndex = 1
console.log(firstElementSavedIndex)
firstElementSavedIndex = 0;
console.log(firstElementSavedIndex)
if (firstElementSavedIndex !== undefined || firstElementSavedIndex !== 0) firstElementSavedIndex -= 1;
console.log(firstElementSavedIndex)
The code I created above I wanted to use as a guard to prevent firstElementSavedIndex from decrementing unless firstElementSavedIndex isn't undefined or 0.
However the code above decrements even if firstElementSavedIndex is 0.
I must be missing something basic, but I havent found any solutions so far.
Any help would be appreciated.
-Hendrik
In the if block the expression becomes
0 !== undefined || 0 !== 0
true || 0 !== 0
true
Since you are using or as long something evaluates to true the whole expression will become true hence the code goes inside the if block.
To fix this you need to replace || with && and make the conditional as savedIndex greater than 0.
let firstElementSavedIndex = 1;
console.log(firstElementSavedIndex);
firstElementSavedIndex = 0;
console.log(firstElementSavedIndex);
if (firstElementSavedIndex !== undefined && firstElementSavedIndex > 0) {
firstElementSavedIndex -= 1;
}
console.log(firstElementSavedIndex);
now it becomes
0 !== undefined && 0 > 0
true && 0 > 0
true && false
false
I have a feeling this isn't possible? I'm trying to check sets of conditions here and my tests should be passing after I moved a couple of those sets out of 2 other methods and into this if statement below as to combine all the checks into one if statement:
if ((move.coordinates.x === 0 && move.coordinates.y === 0 ||
move.coordinates.x === 0 && move.coordinates.y === 1 ||
move.coordinates.x === 0 && move.coordinates.y === 2)
||
(move.coordinates.x === 1 && move.coordinates.y === 0 ||
move.coordinates.x === 1 && move.coordinates.y === 1 ||
move.coordinates.x === 1 && move.coordinates.y === 2)
||
(move.coordinates.x === 2 && move.coordinates.y === 0 ||
move.coordinates.x === 2 && move.coordinates.y === 1 ||
move.coordinates.x === 2 && move.coordinates.y === 2))
{
...then do something
}
Doesn't seem the parens are making a difference here in separating out the conditional sets.
I'm trying to trim down on duplicate code I had those 3 sets in different methods where the logic was mostly the same, but checked for different states.
So I pasted in the two other state sets (sets meaning the group of 3 ors that make up a given state) and trying to check these 3 rows basically in one method instead of splitting out into 3 to cut down dup code.
Simplifying the notation, you have
(x == 0 && y == 0 || x == 0 && y == 1 || x == 0 && y == 2)
||
(x == 1 && y == 0 || x == 1 && y == 1 || x == 1 && y == 2)
||
(x == 2 && y == 0 || x == 2 && y == 1 || x == 2 && y == 2)
Since the operator || is associative, you can remove the parentheses.
And then you can use the distributive property to group the x.
x == 0 && (y == 0 || y == 1 || y == 2) ||
x == 1 && (y == 0 || y == 1 || y == 2) ||
x == 2 && (y == 0 || y == 1 || y == 2)
And even use the distributive property again
(x == 0 || x == 1 || x == 2) && (y == 0 || y == 1 || y == 2)
Finally, you can store the allowed values in an array and use indexOf to avoid repeating the variables:
var values = [0, 1, 2];
values.indexOf(x) >= 0 && values.indexOf(y) >= 0;
you can use logical rules that cover all the possibilities you allow. if you look at the repeating values in your code, you see that you are trying to exhaust all combinations of x values 0,1,2 with combinations of y values 0,1,2. so if you make a rule that will encompass x values from 0 to 2 and the same with y values from 0 to 2, you can simplify your if statement like the example below.
var coordx = move.coordinates.x;
var coordy = move.coordinates.y;
if ((coordx >= 0 && coordx <= 2) && (coordy >= 0 && coordy <=2)) {
// do something
}
One issue I see with your code is the order of operations (take a look here to see the basics), consider using more brackets to be as explicit as possible. It looks like you want to do this:
if (( (move.coordinates.x === 0 && move.coordinates.y === 0) ||
(move.coordinates.x === 0 && move.coordinates.y === 1) ||
(move.coordinates.x === 0 && move.coordinates.y === 2))
||
...
But, if you want to be a little more efficient and clear, I would recommend reformatting your logic with nested if statements:
if (x==0 || x==1 || x==2)
{
if(y==0 || y==1 || y==2)
{
do something...
In all of the JavaScript operator precedence charts I can find (like this one and this one), the logical AND (&&) has slightly higher precedence to the logical OR (||).
I can't seem to figure out an expression where the result is different than it would be if they had the same precedence. I figure there must be some way for it to matter or they'd be listed as having the same precedence if it didn't.
For example:
0 || 2 && 0 || 3
is 3, but it doesn't matter how I slice that up, it's always going to be 3:
(0 || 2) && 0 || 3
0 || (2 && 0) || 3
(0 || 2 && 0) || 3
0 || 2 && (0 || 3)
0 || (2 && 0 || 3)
If I make that first 0 something else (like 4), the result is always 4 because the first || doesn't even look at the right-hand side. If I swap the 0 and 3 in the last || around, the result remains 3.
The closest I've come is
0 || false && "" || NaN
...which is NaN, whereas
0 || false && ("" || NaN)
...is false, but I think that's explained purely by the left-to-right semantics, not by && being higher precedence.
I must just be missing it, for what expression does it matter that && has a higher precedence than ||?
true || false && false
is true
(true || false) && false
is false
true || (false && false)
is true
If they had the same precedence and were left-associative, then e.g. the expression
1 || 0 && 2
would be
((1 || 0) && 2) // evaluates to 2
instead of the
(1 || (0 && 2)) // evaluates to 1
that we get from the "usual" precedence rules.
For your structure … || … && … || … (which would be (((… || …) && …) || …) instead of normal ((… || (… && …)) || …)), you'd get different results for values like 0 0 1 0.
Why does the logical AND have slightly higher precedence to the logical OR?
So that the canonical form of boolean expressions, the disjunctive normal form, does not need any parenthesis.
Example:
1 || 0 && 0 -> (1 || 0) && 0 -> (1) && 0 -> 0
1 || 0 && 0 -> 1 || (0 && 0) -> 1 || (0) -> 1
Negating takes me hours of trial and error until nothing breaks, any method of negating other than intuitively? For example:
//x and y are whole numbers
!((x<9) && (y<=(8-x)))
((x>8) || (y>(8-x)))
The simplest thing is to ignore questions about the domain of values, and treat this as an entirely logical problem. Then we can break it down into cases such as:
!(A || B) ~= !A && !B
!(A && B) ~= !A || !B
!(!A) ~= A
!(x > y) ~= x <= y
!(x >= y) ~= x < y
The first two can easily be extended:
!(A || B || C || D || ...) ~= !A && !B && !C && !D && ...
!(A && B && C && D && ...) ~= !A || !B || !C || !D || ...
So, for one of your examples, we have:
!((x < 9) && (y <= (8-x)))
!(x < 9) || !(y<=(8 - x)
(x >=9) || (y > (8 - x))
We could leave it as this, but as you had additional domain information, ("x and y are whole numbers"), you might incorporate it to return a slightly less specific, but accurate enough in context answer, such as
(x > 8) || (y > (8 - x))
You would have to decide on a case-by-case basis whether this is worth the additional steps. What it might gain is a somewhat reduced codebase, it can also lose in a less transparent link to the original format.