In Javascript, what would be the best way to evaluate several conditions when taking into consideration variables that could be undefined? For instance, I want to evaluate if x > y only if x is NOT undefined (has a value), and if it is undefined, continue to proceed to the next condition.
Something like:
if(x && x > y && a && a > b && c < d && e > f) ....
Here I want to see if x is defined, and then evaluate if x is greater than y, then go to evaluate if a is defined and evaluate if a is greater than b, then evaluate if c is less than d and etc. So here I want it so that if x or a is undefined CONTINUE to proceed to evaluate c < d and e > f
if(
x // if exists
&& x > y // (if x is defined then evaluate x > y, if not then go to:
&& a // if exists
&& a > b // (if a is defined then evaluate a > b, if not then go to:
&& c < d
&& e > f
) {
....
}
Here if the variables are are undefined then the whole statement is all false... what are some solutions for this that are clean?
You can do x > y directly, You need not do x && x>y, because they will produce same result and x>y syntactically correct as well
if(x>y) //when x=undefined and y=10, x>y will be false because undefined>10 is false
//when x=undefined and y=undefined x>y will be false because undefined>undefined is false
//when x=10 and y=undefined x>y will be false because 10>undefined is false
if(x > y && a > b && c < d && e > f)
Related
so here is the scenario
if ( ( a >= b) && ( (c < d) && (d != '') ) )
cannot get this logic on this to work correctly
so if d = '' it would cause that to be false. which would mean that the whole thing would equate to false. Problem is I need it to trigger when a >= b but also needs to include the and for c < d but only if d != '', in other words ignore the c < d part if d = '', otherwise used the c < d part to prevent a >= b from triggering.
hope this is making sense. I am trying to avoid doing and if/else or switch.
One comment would be if you are not absolutely avoid using if/else or switch then you could define funcitons use them and use thiss functions in your statement above.
Apart from that, changing the order of some expressions might do what you want. c < d would not be evaluated if d = '' is not true. a >= b would not be evaluated if the expresion before second or, ||, is true or d == '', empty string, is true.
if ((d != '' && c < d) || (d != '' && c >= d && a >= b))
which is;
if (d != '' && (c < d || a >= b))
thanks for your suggestions, I found a workaround though
I just put
if (d == '') { d = Infinity; }
then
if ( (a >= b) && (c < d) )
and that solved it
thanks for everyone's help
I have a function which appears to always be returning true on the first condition irrelevant of input. I have been reading about using switch versus else if as I have 16 conditions to check and I want to ensure I have working 'best practice'
Can I achieve the same thing using both options:
function lsaupdateTotals() {
var x = variablename.value;
var y = variablename2.value;
if (x = 1) || (y = y > 1 && y < 280) {
rdlsa = 7.45;
} else if (x = 2 || (y = y > 281 && y < 460)) {
rdlsa = 11.65;
/ or switch: /
switch (x) {
case 1:
case y > 1:
case y < 280:
y = 7.45;
break;
}
There are several problem in your code:
In javascript, to compare 2 numbers (or strings) you have to use the syntax ===, so if (x = 1) should became if (x === '1') (as I'm expecting x is a string).
The if condition should be in a parenthesis: if (x = 1) || (y = y > 1 && y < 280) { => if ((x === 1) || (y === y > 1 && y < 280)) {
It's not clear what you mean with y = y > 1 (or y === y > 1) in first if (second parenthesis)
In switch/case syntax you cannot use y>1, please refer to switch/case syntax (internet is full of documentation)
When you put an assignment into the if (using = instead of ===) the if statement consider true the condition if the value after the = is not null, 0, empty string, false or undefined, for this reason when you write if(x=1){ the condition is always true.
You've got a few issues in your code:
You're using = instead of == or === to check equality in your if statements. A single = sign always means "set equal to", not "is equal to?".
In your if statement your parens make things a bit ambiguous. It's possible that this works just fine, but wrapping the entire question in parens is guaranteed to work as intended while also being completely clear.
Rewriting your if statement according to the above:
if (x == 1 || (y == y > 1 && y < 280)) {
rdlsa = 7.45;
}
else if (x == 2 || (y == y > 281 && y < 460)) {
rdlsa = 11.65;
}
(EDIT: Note that the y == y > 1 part is almost definitely not doing what you want it to. That's asking "is y the same thing as y > 1?")
In your switch, think of the value in each case as being a place holder for what you're putting into it. So in your example, using y>1 doesn't make sense to evaluate against x, because it's asking if x is *equal to y>1, but y>1 is always true or false and is independent of x.
you are getting the conditions wrong.
Please replace your code with the below lines
function lsaupdateTotals() {
var x = variablename.value;
var y = variablename2.value;
if ((x == 1) || (y > 1 && y < 280)) {
rdlsa = 7.45;
} else if ((x == 2) || (y > 281 && y < 460)) {
rdlsa = 11.65;
}
/ or switch: /
switch (x) {
case 1:
case y > 1:
case y < 280:
y = 7.45;
break;
}
According to Mozilla, the === operator has higher precedence than the || operator, which is what I would expect.
However, this statement evaluates to the number 1, rather than false.
let x = 1 || 0 === 0; // x === 1;
You have to wrap in parentheses to get a boolean:
let x = (1 || 0) === 0; // x === false;
What is the explanation?
Note: This is not a duplicate of this question, which does not have anything about equality operators - JavaScript OR (||) variable assignment explanation
Higher operator precedence is like a parenthesis around the operands.
let x = 1 || (0 === 0);
The second part gets never evaluated, because of the truthy value of 1
.
|| is a short circuit operator and conditions are evaluated from left to right.
So in left || right, if the left condition is true, the whole condition is evaluated to true and the right one is never evaluated.
In
let x = 1 || 0 === 0; // x === 1;
x = 1 assigns 1 to x and the second condition after || is never evaluated as if (1) is evaluated to true.
And in
let x = (1 || 0) === 0; // x === false;
(1 || 0) is evaluated to true as if (1) is still evaluated to true.
And then true === 0 is evaluated to false.
So x is valued to false.
Can someone explain to me or point me to documentation as to why the following function doesn't work?
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if ((x && y && z) === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
I know that I can type it out the long way as follows:
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
But I'm really trying to understand why the first doesn't work and also if there is a better way of typing the second if/then statement or if that is just the way it will always have to be.
Thanks!
The expression
((x && y && z) === 1)
first involves the evaluation of (x && y && z). To evaluate that, JavaScript tests, in sequence, the values of x, y, and z. If, left to right, one of those values when coerced to boolean is false, evaluation stops with that (uncoerced) value as the value of the whole thing. Otherwise, the value of that subexpression will be the value of z, because it's the last subexpression in the && sequence.
In this case, x, y, and z are all non-zero numbers, so the overall result will be 1, because z is 1.
What you seem to want to be able to do is test whether all of a set of subexpressions are equal to the same value. That, as you've found, can only be determined by explicit comparison. It's also something that could be done by creating a list and then using array functions to perform the tests, which would be useful when there are more than just three subexpressions to test.
Also, on a stylistic note:
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
Performing tests with relational operators like === generates boolean values. It's more concise to take advantage of that:
function logicTest() {
return x === 1 && y === 1 && z === 1;
}
When reading source of D3.js I saw x >= x pattern. If it is for detecting NaNs among numbers, why not just isNaN(x) or x == x?
Source, where I encountered it:
d3.min = function(array, f) {
var i = -1, n = array.length, a, b;
if (arguments.length === 1) {
while (++i < n) if ((b = array[i]) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = array[i]) != null && a > b) a = b;
} else {
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
}
return a;
};
From my investigations, d3.min is supposed to work on any kind of orderable values, not only numbers. isNaN would only work numbers.
d3 was actually using == at some point. This commit introduced the x == x test:
Unlike Math.min and Math.max, it doesn't make sense to return negative or positive infinity for d3.min and d3.max; the D3 functions return the minimum value according to an arbitrary ordering, not by numeric value. Instead, the minimum or maximum of an empty array, or an array that contains only degenerate values, should always be undefined.
This commit changed x == x to x <= x (which was later again changed to x >= x):
In addition to NaN, which is not equal to itself, you can have objects that are not orderable due to defined valueOf functions which return NaN. For example:
var o = new Number(NaN);
Here, o == o is true, but o <= o is false. Therefore it was possible for d3.min, d3.max and d3.extent to observe these non-orderable values rather than ignore them as intended. The fix is to check !(o <= o) rather than o == o.
OK, I see that x >= x gives false for both NaN and undefined. (Unlike isNaN(x) or x == x.)
EDIT: While it is one of the use cases of x >= x, in this case (thx #Felix Kling for pointing this out) undefined is already being checked.