ternary operation in js - javascript

Maybe I do not understand ternary operation but
if I am right it's
test ? true : false
So this should give
function toto(x, y)
{
return (x > 0 ? x < 7 ? true : false : false &&
y > 0 ? y < 6 ? true : false : false)
}
true only if 0
but if I do
toto(4,6)
it returns true, why? What am I missing ?

just do like this :
function toto(x, y)
{
return (x > 0 ? x < 7 ? true : false : false ) &&
( y > 0 ? y < 6 ? true : false : false)
}
with the bracket before and after the exp1 and exp2
and yes it's a bit unreadable ^^
edit : I also would do
return (x > 0 && x < 7) && (y > 0 && y < 6)

you need eslint to format your code ,this is the formatted code,see:
function toto(x, y) {
return x > 0
? x < 7
? true
: false
: false && y > 0
? y < 6
? true
: false
: false
}
image:
I think ,it is easier to understand

Aren't you trying to achieve this? chceking whether the x is from 0..7 and y is 0..6?
function toto(x, y)
{
return (x > 0 && x < 7) && (y > 0 && y < 6 );
}

Operator precedence affecting it here
function toto(x, y)
{
return ((x > 0 ? x < 7 ? true : false : false) && (y > 0 ? y < 6 ? true : false : false))
}

Related

What does the multiplication operator do in this code?

So I saw this code and have no clue what the * in sortBy[i].direction*(...) does. Can anyone break this down for me and help me understand this code?
result = sortBy[i].direction*(a[ sortBy[i].prop ] < b[ sortBy[i].prop ] ? -1 : (a[ sortBy[i].prop ] > b[ sortBy[i].prop ] ? 1 : 0));
The * operator multiples the value of sortBy[i].direction with
-1 if a[sortBy[i].prop] < b[sortBy[i].prop];
1 if a[sortBy[i].prop] > b[sortBy[i].prop];
0 otherwise.
Look at this as
result = sortBy[i].direction *
(a[sortBy[i].prop] < b[sortBy[i].prop]
? -1
: (a[sortBy[i].prop] > b[sortBy[i].prop]
? 1
: 0));

Improve an if statement chain

if (firstPositionCpc && (firstPosition > 0 && firstPositionCpc <= maxCPC)) {
var newCPC = firstPositionCpc;
} else if (topOfPageCpc && (topOfPageCpc > 0 && topOfPageCpc <= maxCPC)) {
var newCPC = topOfPageCpc;
} else if (firstPageCpc && (firstPageCpc > 0 && firstPageCpc <= maxCPC )) {
var newCPC = firstPageCpc;
} else {
var newCPC = minCPC;
}
Here is some wrong scenario
KeywordIdReport :197857118477
campaignName :BP 2015 QC (FR)
maxCPC : 3.00
OldCPC :0.46
firstPositionCpc : --
topOfPageCpc : 0.46
firstPageCpc : 0.05
NewCPC : --
Here NewCPC needs to be a number. Hence, firstPositionCpc, topOfPageCpc and firstPageCpc need to exist and be a number.
KeywordIdReport :97483945
campaignName :BP 2015 QC (FR)
maxCPC: 3.00
OldCPC :1.96
firstPositionCpc : 4.28
topOfPageCpc : 1.68
firstPageCpc : 0.85
NewCPC : 4.28
Here NewCPC needs to be lower or equal to maxCPC. Normally, the answer should be 1.68 instead of 4.28 for NewCPC.
How could I fix the chain of if statement so that it will fix the wrong scenarios?
UPDATE
Now after improvement, how could I say that the type of firstPositionCpc, topOfPageCpc and firstPageCpc exist and need to be a number?
Hence, firstPositionCpc, topOfPageCpc and firstPageCpc need to exist and be a number.
The above doesn't really make sense given that you have 3 comparisons, so my answer will lean on the assumption that you want firstPosition > 0.
So I need to check if a value type is number and if that number is in some bound so taking your first if statement:
if (firstPositionCpc && (firstPosition > 0 && firstPositionCpc <= maxCPC)) {
var newCPC = firstPositionCpc;
}
I would change it to the following:
if(typeof(firstPositionCpc) == 'number' && firstPositionCpc <= maxCPC && firstPosition > 0){....}
typeof() reads the type of the parameter and returns a string indicating the value.
See here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof

Multiple Sets of Sets of ORs

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...

Boolean equality

I got this out of an exam question, and couldn't understand how the solution works. This function is supposed to return "true" if the values "x" and "y" are equal, and return False otherwise.
The solution:
function equal_boolean (x , y) {
return x ? y : y ? x : true;
}
Why does this work? As much as I can understand, it would turn out to be evaluating if X is true. If X is true, it would return Y. How is X supposed to be "true"?
If it isn't, it would evaluate whether Y is true, if it's true it would return X, and if it isn't - it would return True.
Is there something wrong with my understanding?
return x ? y : y ? x : true;
parses as
if x
return y // if y is true, then x == y. if y is false, then x != y
else (x is false)
if y
return x // x is false and y is true, y != x, return false
else
return true // x is false and y is false, return true
This is of course a pretty convoluted way to express boolean equality (aka Logical biconditional aka iff). More natural would be an expression like this:
(x && y) || (!x && !y)
The first thing you should do is group the ternary operators together:
(x ? y : (y ? x : true))
if x is true, then return y, whose value also tells you whether x and y are equal
if x is false, then start with the second ternary:
if y is true, then return x (false) as the two are not equal
if y is false, then x and y are equal, so return true
Let's try expanding this a bit:
var myBool = x ? y : (y ? x : true)
return myBool;
First block
x ? y : ...
if X is true, then return value of Y. If Y happens to be true, both are equal. Otherwise return false (no match).
Second block if X was false:
y ? x : true
if Y is true, return X. X was false, so false is returned (no match)
if Y is false, return true - both values are false.
First identify the expressions
return x ? y : y ? x : true;
//turns into
return x ? y : (y ? x : true);
Replace the ?: ternary operators by if statements
if (x) {
return y;
} else {
//here x is false, so we will be able to replace x by false in the next step
if (y) {
return x;
} else {
return true;
}
}
Make if statements more verbose, replace return x by return false
if (x == true) {
return y;
} else {
if (y == true) {
return false;
} else {
return true;
}
}
Finally replace return y; by if (y == true) { return true; } else { return false; }, and check all the possibilities
if (x == true) {
if (y == true) {
return true; // x == true and y == true
} else {
return false; // x == true and y == false
}
} else {
if (y == true) {
return false; // x == false and y == true
} else {
return true; // x == false and y == false
}
}
It works. (As long as x and y are booleans)

Multiple comparison operators in a JavaScript boolean expression

I'm trying to check whether the variable y is less than x and greater than z, but this boolean expression is returning false for some reason. Does JavaScript allow boolean expressions to be written concisely like this? If so, what is the correct syntax?
x = 2;
y = 3;
z = 4;
if(x > y > z){
alert("x > y > z"); //Nothing happens!
}
Try using the logical and operator:
if (x > y && y > z) {
to guarantee both conditions are true.
DEMO: http://jsfiddle.net/3sxvy/
If you need to put this into a function, you could try:
function compareNumbers(direction) {
var inOrder = (function () {
if (direction === "desc") {
return function (current, before) {
return current <= before;
};
} else if (direction === "asc") {
return function (current, before) {
return current >= before;
};
}
})();
var valid = true;
for (var i = 2; i < arguments.length; i++) {
if (!inOrder(arguments[i], arguments[i-1])) {
valid = false;
break;
}
}
return valid;
}
if (compareNumbers("desc", 33, 5)) {
console.log("Good");
} else {
console.log("Bad");
}
DEMO: http://jsfiddle.net/kn6M4/1/
Change your test to
if (x > y && y > z){
When you write (x > y > z), this is equivalent to ((x>y)>z), so you're comparing a boolean (x>y) to z. In this test, true is converted to 1, which isn't greater than 2.
You want
if(x > y && y > z){
alert("x > y > z"); //Nothing happens!
}
Javascript will try to parse your original statement from left to right and you'll end up comparing z to a boolean value which will then be parsed to a number (0 or 1).
So your original statement is equivalent to
if( (x > y && 1 > z) || (x <= y && 0 > z))

Categories

Resources