I have an if test in JavaScript which achieves what I want but not as elegantly as possible. It goes like this:
if (x > y || p < q) {
// don't do anything
} else {
doSomeFunction();
}
If there any way to flip the logic of this so there's only a single if statement without having to have a dummy if-condition as well as the else condition?
You can use the ! operator to invert the condition:
if (!(x > y || p < q)) {
doSomeFunction();
}
Or simply rewrite the condition like this:
if (x <= y && p >= q) {
doSomeFunction();
}
Note: See De Morgan's laws for an explanation about why these two conditions are equivalent.
You can simply invert the comparisons and the logical OR.
if (x <= y && p >= q) {
doSomeFunction();
}
Along with the other answer, the last option (less readable) is :
(x > y || p < q) || doSomeFunction();
If the left bracket is true, it will NOT execute the function.
Related
I'm trying to write this code for an after effects expression that will move an object a calculated x distance over n number of frames. The movement over each frame is parabolic rather than linear, and so I'm using the nth root code to determine how much the object should move over each frame. I'm putting each of the nth roots into an array to access later when setting the positions for each move.
I'm still learning javascript mainly for AE, so please bear with me if there are things in here I don't fully understand. I think I understand, which is why I'm not sure I'm getting the undefined output for certain n values. Here's the code:
//get Nth root
function nthroot(x, n) {
ng = n % 2;
if ((ng == 1) || x < 0)
x = -x;
var r = Math.pow(x, 1 / n);
n = Math.pow(r, n);
if (Math.abs(x - n) < 1 && (x > 0 === n > 0))
return ng ? -r : r;
}
distance=1515; //will be determined by another portion of the AE expression
frames=6; //will be set by expression control in AE
const myArray = [];
let i = 1;
while (i <= 6) {
myArray.push(nthroot(distance,i++));
}
console.log(myArray);
document.getElementById("demo2").innerHTML = myArray
I put it into a fiddle here. What am I doing wrong? Thanks in advance for any help!
Your "nthroot" function doesn't return values consisistently: if you look at the end of your function you can find this part:
if (Math.abs(x - n) < 1 && (x > 0 === n > 0))
return ng ? -r : r;
if you notice, you are returning a value only if the condition in the if statement is fullfilled, otherwise you are not returning any value.
In JavaScript, a function that doesn't return any value returns "undefined" instead.
In other words, when
Math.abs(x - n) < 1 && (x > 0 === n > 0)
is true, you are returning either "r" or "-r", but when the condition is false you aren't returning any value, so the function returns "undefined".
You have to handle the false case.
I was writing an algorithm to compare how many bits are different between 2 numbers using this function
var hammingDistance = function(x, y) {
let result = 0;
while (x !== 0 || y !== 0) {
// This line is incorrect
if (x & 1 !== y & 1) result++;
x = x >> 1;
y = y >> 1;
}
return result;
};
But my result is always 1 less than the correct answer, and it turns our my function is wrong when comparing the left most digit, such as 0011 and 0100. It returns 2 instead of 3.
https://i.imgur.com/P46RyZr.png
I can use XOR instead of !== to get the correct answer. But I'm wondering why?
Your problem is that !== has a higher precedence than &. So your condition is actually (x & (1 !== y)) & 1. Use explicit grouping instead:
if ((x & 1) !== (y & 1)) result++;
It works with ^ because that has a lower precedence than &.
In other words, why doesn't this show an alert?
var x;
if (x = 1 && x > 0) {
alert(x);
}
As far as I understand, x = 1 should assign 1 to x and also return 1. The x > 0 check is failing. Why?
Actually, the && operation will have precedence over the assignment.
In you case, x will be the result of 1 && x > 0 which is false.
var x;
if (x = 1 && x > 0) {
alert(x);
}
console.log(x); // false
You can enforce the order of operations using parentheses, as shown by Nina Scholz.
You need some parens to separate the assignment from the ongoing expression.
var x;
if ((x = 1) && x > 0) {
alert(x);
}
I'm learning about canvas by making a simple RPG.
I'm trying to make it so that if you walk into a certain area, it runs a function. So I used an if:
if (x<150, x>50, y<150, y>50) {
(code I want to execute)
}
But even when the statement is false, it's still considered true. I want it so that all statements in the parentheses must be true for the code to execute. Any help?
Use &&:
if (x < 150 && x > 50 && y < 150 && y > 50) {
// (code I want to execute)
}
Or to separate each part for readability:
if ((x < 150) && (x > 50) && (y < 150) && (y > 50)) {
// (code I want to execute)
}
To learn more, check out:
Logical Operators
Use &&, not ,:
if (x<150 && x>50 && y<150 && y>50) {
Using && means you want all of the conditions between the brackets evaluated. The code below will be executed if x is less the 150 AND y is less than 150 AND x is greater than 50 AND y is greater than 50. If only 3 of the conditions are satisfied, the code will not run. As a result your new code will look like this:
if (x < 150 && x > 50 && y < 150 && y > 50) {
// (code I want to execute)
}
Using || basically means or, and the code gets executed if any of the conditions are valid. The code below will be executed if x is less the 150 OR y is less than 150 OR x is greater than 50 OR y is greater than 50. In effect, if even 1 of the conditions is met the code will run.
if (x < 150 || x > 50 || y < 150 || y > 50) {
// (code I want to execute)
}
You can find a simple tutorial here
I want to check the following
1: Is x a number
2. If x is less that 5 or greater than 15, sound alert
3. If all is ok, callMe()
var x = 10;
if (isNaN(x) && ((x < 5) || (x > 15))) {
alert('not allowed')
}
else
{
callMe();
}
What am I doing wrong?
var x = 10;
if (isNaN(x) || (x < 5) || (x > 15)) {
alert('not allowed')
}
else
{
callMe();
}
This way, if x is not a number you go directly to the alert. If it is a number, you go to the next check (is x < 5), and so on.
All the other answers about the && vs || are correct, I just wanted to add another thing:
The isNaN() function only checks whether the parameter is the constant NaN or not. It doesn't check whether the parameter is actually number or not. So:
isNaN(10) == false
isNaN('stackoverflow') == false
isNaN([1,2,3]) == false
isNaN({ 'prop' : 'value'}) == false
isNaN(NaN) == true
In other words, you cannot use it to check whether a given variable contains a number or not. To do that I'd suggest first running the variable through parseInt() or parseFloat() depending on what values you expect there. After that check for isNaN(), because these functions return only numbers or NaN. Also this will make sure that if you have a numeric string then it is also treated like a number.
var x = 10;
if (isNaN(x) || (x < 5) || (x > 15)) {
alert('not allowed')
}
else
{
callMe();
}