Are multiple comparison operators possible in javascript? [duplicate] - javascript

This question already has answers here:
Dual or triple (or even multiple) comparison in JavaScript
(3 answers)
Closed 2 years ago.
So i was writing in the Browser console
4 < 5
true
4 < 5 < 10
true
7 < 4 < 10
true
The first two statements look ok, why is the last statement also correct? I would have thought (as in mathematics) the expression would be 'AND'ed ? can any one point me to MDN or similar resource which talks about this and the rules ?

What Javascript does, is evaluate the left side first:
4 < 5 => true
It then continues on the rest:
true < 10 => true
because true on the left side is coerced to a number (1), and 1 < 10 === true. (false in comparisons with numbers is coerced to 0).
Check these funny-looking "goofs":
console.log(3 < 2 < 1)
console.log(1 < 1 < 1)

Beside the not working approach to write a continuing check with more than one copmparison operator, and while the next comparison takes place the the result of the previous comparison, you could take an array and a function for the comparison operator and iterate the items for every pair to check. Then return the result.
const compare = (values, fn) => values.slice(1).every((b, i) => fn(values[i], b));
console.log(compare([7, 4, 10], (a, b) => a < b)); // false
console.log(compare([4, 7, 10], (a, b) => a < b)); // true
console.log(compare([2, 1, 0], (a, b) => a > b)); // true

console.log( false < 10) // true
console.log( true < 10) // true
because false (0) is less than to 10
and true (1) is also less than to 10.

4 < 5 evaluates to true. Then true is compared with 10. Javascript converts true to 1 and as 1 is smaller than 10 the result is true.
With this logic if you try 4 < 5 < 3 this will also return true with the same logic, and 4 < 5 < 1 will return false.

Related

Recursive method keeps going, but in the opposite direction. Why?

So I'm trying to familiarize myself with recursion and Javascript. So I wrote a simple method to try it out. I'm pretty new to Javascript syntax so I'm not really sure where I'm going wrong. Here is the method.
export const IsEven = (n) => {
if(n > 1){
n -= 2;
IsEven(n);
}
else{
var bool = NumberToBool(n);
return bool;
}
}
When stepping through, n does reach 0 or 1 and defines it as true or false. However, the method does not stop at the return statement. Instead, it turns around and starts adding 2 to n. I cannot understand how that is even possible, does anyone have an idea on what is going on?
Thanks
You can use mathematical induction to solve the vast majority of recursive problems -
if n is negative, return the result of isEven(-n)
(inductive) n is zero or greater. if n is greater than one, return the result of the recursive sub-problem, isEven(n - 2)
(inductive) n is neither negative nor greater than 1. this means n is zero or one. zero is even, one is odd. return n == 0 gives us the correct result for both.
const isEven = (n) => {
if (n < 0) return isEven(n * -1) // 1. n is negative
else if (n > 1) return isEven(n - 2) // 2. n is 2 or more
else return n == 0 // 3. n is 0 or 1
}
for (let i = -10; i<10; i++)
console.log(i, isEven(i))
Recursion is a functional heritage and so using it with functional style yields the best results. if statements do not evaluate to a value and instead rely on side effects like return to compute the result. Below we use expressions which evaluate to a value and it allows us to skip a lot of the syntactic noise that comes with imperative style. Now isEven reads more like a formula -
const isEven = n =>
n < 0
? isEven(n * -1) // 1. n is negative
: n > 1
? isEven(n - 2) // 2. n is 2 or more
: n == 0 // 3. n is 0 or 1
for (let i = -5; i < 5; i++)
console.log(i, isEven(i))
n
isEven(n)
-5
false
-4
true
-3
false
-2
true
-1
false
0
true
1
false
2
true
3
false
4
true
isEven can be defined using a synergistic counterpart, isOdd, where each can be defined in terms of the other. This technique is called mutual recursion -
const isEven = n =>
n < 0
? isEven(-n)
: n == 0
? true
: isOdd(n - 1)
const isOdd = n =>
n < 0
? isOdd(-n)
: n == 0
? false
: isEven(n - 1)
for (let i = -5; i < 5; i++)
console.log(`i:${i} isEven:${isEven(i)} isOdd:${isOdd(i)}`)
n
isEven(n)
isOdd(n)
-5
false
true
-4
true
false
-3
false
true
-2
true
false
-1
false
true
0
true
false
1
false
true
2
true
false
3
false
true
4
true
false

Why is 1<x<3 always true?

I'm learning TypeScript, and in the getting started page, they talk about how unexpected javascript is.
Source: https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html
if ("" == 0) {
// It is! But why??
}
if (1 < x < 3) {
// True for *any* value of x!
}
But I still don't understand why 1<x<3 is always true? For example if I let x=10, it will not be true by logic, but why they said it always true?
1 < x < 3 actually is doing this:
(1 < x) < 3
Or even more long form:
const tempVarA = 1 < x
const tempVarB = tempVarA < 3
So 1 < x is either true or false. Then the next step is true < 3 or false < 3. Those don't make much sense as comparisons, but let's see what javascript does with that:
console.log(true < 3) // true
console.log(false < 3) // true
Weird, but let's dig deeper:
console.log(true >= 0) // true
console.log(true >= 1) // true
console.log(true >= 2) // false
console.log(false >= 0) // true
console.log(false >= 1) // false
console.log(false >= 2) // false
It seems that true is being treated as 1 and false is being treated as 0. To verify that let's compare with == (instead of ===) so that it coerces the type of the data for us.
console.log(true == 1) // true
console.log(true == 0) // false
console.log(false == 1) // false
console.log(false == 0) // true
So 1 < x < 3 is always true because false becomes 0 or true becomes 1, and both 0 and 1 always less than 3.
Explanation:
in javascript, comparison operators <, <=, >, >=, ==, and != coerce their operands to make them comparable when they are different types. So when comparing a boolean to a number it coverts the boolean to a number, 0 or 1.
This is why you should almost always use === instead of ==, and why this is a type error in typescript:
const a = true < 3
// Operator '<' cannot be applied to types 'boolean' and 'number'.(2365)
Short version
Javascript and typescript lack a chainable comparison operator.
Did you mean to do this?
1 < x && x < 3
in other words: true is 1 and false is 0. Therefore 1 < x < 3 with x = 5 is as if it executes (1 <5) <3 and writes to 1 <5 = 1 (true) and then 1 <3 = 1 (true). If instead x were 0? Ok 1 <0 is false (0) consequently 0 <3 is true (1)

Why is [1,2,3] <= [1,2,3] true in javascript? [duplicate]

I'm trying to compare two arrays in javascript.
What I'd like is:
a < b &iff; ∃ i ≥ 0 s.t. a[i] < b[i] and ∀ 0 ≤ j < i, a[j] = b[j]
So arrays of non-negative numbers work as desired:
firebug> [0,1,2,3,4] < [1,0,0]
true
And comparing negative numbers with zero works as expected:
firebug> [-1, 1] < [0, 0]
true
But comparing negative numbers with negative numbers is... suprising:
firebug> [-2] < [-1]
false
firebug> -2 < -1
true
What's going on here, so I can correct my intuition for what array comparison means in javascript?
The array is converted to a string, which comes down to .join(), which in turn joins the elements with a comma (,) as delimiter.
"-1,1" < "0,0" === true
because the character code of - (45) is smaller than the character code of 0 (48).
On the other hand,
"-2" < "-1" === false
because the second character codes are compared (the first are both -, so that doesn't give a result yet), and the character code for 2 (50) is bigger than the character code of 1 (49), so this yields false.
It comes down to a lexographical sorting (i.e. by character codes) and not a numerical one, even if the elements are numbers (because of the string coercion).
Basically comparing arrays is not recommended. It is implicitly defined as string comparison, but this can yield surprising results.
There's no such thing as JavaScript array comparison in any form similar to what you describe.
What's happening in all cases is that your arrays are being converted first to strings by joining their contents together. Thus, the string "-2" is not less than the string "-1", because the character "2" comes after "1" in the character set. Similarly, "-1,1" is less than "0,0" because the "-" character comes before the digits.
You can see for yourself that in all cases your comparisons:
array1 < array2
get exactly the same results as:
("" + array1) < ("" + array2)
or:
array1.join(",") < array2.join(",")
I couldn't find an answer about how to actually compare arrays in Javascript and get "expected" results, so here is the code
compareArrays = function(a, b) {
var elA, elB, i, len;
for (i = 0, len = Math.min(a.length, b.length); i < len; i++) {
elA = a[i], elB = b[i];
if (elA > elB) return 1;
if (elA < elB) return -1;
}
return b.length - a.length;
};
console.log(compareArrays([-2], [-1])) # -1
console.log(compareArrays([], [])) # 0
console.log(compareArrays([null], [undefined])) # 0
console.log(compareArrays([1, 2, 3], [1, 2, 3, 4])) # 1
console.log(compareArrays([0, 2], [0, 1])) # 1
console.log(compareArrays([1], [NaN])) # 0
console.log(compareArrays([NaN], [1])) # 0

Javascript chained inequality gives bizarre results [duplicate]

This question already has answers here:
Can I use chained comparison operator syntax? [duplicate]
(6 answers)
Closed 8 years ago.
(0 <= 0 <= 0) === false
(-1 < 0 <= 0 <= 0) === true
What's going on here? Does Javascript actually have inequality chaining that's just wrong in some cases?
Typed up the question and then was struck by the answer. Javascript does not have inequality chaining. Rather, 0 <= 0 <= 0 becomes true <= 0, which is evaluated as 1 <= 0. Indeed, 0 < 0 <= 0 evaluates to true.
There is no chaining of operator but precedence. Here all the operators have the same priority so the operations are done from left to right.
When your comparison involves a boolean, the MDN explains how the comparison works :
If one of the operands is Boolean, the Boolean operand is converted to
1 if it is true and +0 if it is false.
This means the first operation is decomposed according to priorities as
((0 <= 0) <= 0)
which is
true <= false
which is
false
And the second one is
(true <= 0) <= 0
which is
false <= 0
which is true.

How come this is true? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does (0 < 5 <3) return true?
How come this is true?:
console.log(100 < 210 < 200); // outputs true
That's equivalent to:
console.log((100 < 210) < 200);
which is equivalent to:
console.log(true < 200);
And this evaluates to true because when using operators like <, true is treated as if it were a 1
Consequently, the following will evaluate to false:
console.log(true < 0)
100 < 210 < 200 is equivalent to (100 < 210) < 200 which is true < 200 which is 1 < 200 which is true.
That last bit (true becoming 1) may be a bit surprising. It's the result of how JavaScript does relational operations (Section 11.8.5 of the spec), which says amongst other things that if the relation is between a non-number (other than null or undefined) and a number, you convert the non-number to a number, and the conversion of true to a number results in 1 (Section 9.3 of the spec.)

Categories

Resources