Javascript (-1 <= 5 <= 1) === true? - javascript

I want to validate that a given number is within a given range:
function validate(min, max, amount) {
return (min <= amount <= max);
}
But this does not seem to work properly. I know I can do it with two comparison and a logical AND, but I would like to it in one comparison. Is there any NATIVE javascript way to realize this?

Use this instead :
return (min <= amount && amount <= max);
There is no shortcut. And there is a good reason the JavaScript engine can't guess your intent : what you typed was valid, it just isn't interpreted as you'd like. You were testing, in fact
((min <= amount) <= max)
and the result of the first comparison, which is a boolean, is converted to 0 or 1 for the second one (more details here about operators precedence, those comparison operators are left-to-right).
If you really want a shortcut, you could do this :
Number.prototype.isin = function(m,M) {
return m<=this && this<=M;
};
console.log(0.5.isin(1,2)); // logs false
console.log(3..isin(2,5)); // logs true
but I personally would use the standard solution with && that everybody can read and which doesn't involve an additional function call.
Aside : I could have called my function in instead of isin but it might break ES3 browsers.

Operators ( == , <= , < , >= , == ) take only 2 arguments.
When there are more arguments it uses mathematical order of computing. So in fact your code behave like:
min <= amount // true
true <= max // this is illogical
It's also optimal, because when executing logical statements and finding something like:
if(false && (some computing))
It will ignore (some computing) because result will be always false
This is very common practive in every language. Test like this will not have NullPointerException error, because first argument is already false.
if(obj != null && obj.getValue() > 10) //C++,Java, etc.
if(obj !== undefined && obj.val() > 10) // javascript
if(obj.length != 0 && obj.val() > 10) //jQuery

Related

Javascript Odd or even Algorithm question?

I already know this wouldn't work If I passed something like 0 or 1, but why wouldn't it work If it managed to work with 2 and 7.
I'm still new to Javascript programming so I'm just trying to figure out why adding
if(number = number % 2 == 0) or the other wouldn't work.
Here's the code:
function even_or_odd(number) {
if(number = number % 2 == 0) {
return "Even"
}else if(number = number % 2 !== 0) {
return "Odd"
}
};
= is an assignment operator. It assigns the value of the expression on the right-hand side to a variable on the left-hand side.
== is an equality operator. It tests the equality of the result of both the left and right-hand-side expression.
Since you're using = and inadvertently assigning number to the value of your expression on the right, it will always evaluate to a truthy value and return "Even". To fix, remove the number = from each of the expressions:
function even_or_odd(number) {
if(number % 2 == 0) {
return "Even"
}else if(number % 2 !== 0) {
return "Odd"
}
};
console.log(even_or_odd(0));
console.log(even_or_odd(1));
MDN has a great section on this in their if...else page:
It is advisable to not use simple assignments in a conditional expression, because the assignment can be confused with equality when glancing over the code. For example, do not use the following code:
if (x = y) {
/* do something */
}
If you need to use an assignment in a conditional expression, a common practice is to put additional parentheses around the assignment. For example:
if ((x = y)) {
/* do something */
}

Why is the `n===0` used, as `-0===0` and `0===0` are both true?

function isNegZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
I am reading the book You don't know JS and found this piece of code there. This is the function to check if the passes number is a -0. I failed to understand as to why the first condition in the comparison is mentioned as it is always going to be true (unless I am wrong in understanding it). Please help.
It’s always going to be true for zero. You want isNegZero(n) to not only be false for +0, but also for any number that is not zero.
> let n = -Number.MIN_VALUE
> n === 0
false
> 1 / n === -Infinity
true
The return value is the two comparisons '&&'ed together. Since it short circuits, if any number outside of 0 or -0 is passed, it will run the first comparison and then return false without ever needing to look at the second.

Using conditional operator to run more than one statement will not work

function isPrime(num) {
//TODO
let primeNum = false;
let prime = (num == 0 || num == 1) ? primeNum = false : (num == 2) ? console.log("2 is prime") :
(num % 2 == 0) ? console.log("num is divisable by 2 therefore is not prime") : {
console.log("number may be prime");
primeNum = true;
}
return primeNum;
}
Im attempting a challenge off of codewars to test if a num is prime. On my final conditional I want to print to console and set a value to primeNum. It seems to work fine if i do one or the other but not both.
I know its possible to do by writing a separate function containing both statements and having it be called instead or that I could use if and else statements but I'm trying to follow best practices here.
If you have to execute multiple things inside a single expression (such as inside one of the parts of the conditional operator), you may use the comma operator inside of parentheses. For example:
const condition = false;
const result = condition ? 'foo' : (
console.log('falsey!'),
'bar'
);
console.log(result);
Or, for your code:
function isPrime(num) {
const primeNum = (num == 0 || num == 1)
? false
: (
num == 2
? ( console.log("2 is prime"), true)
: (
num % 2 == 0
? (console.log("num is divisable by 2 therefore is not prime"), false)
: (console.log("number may be prime"), null)
)
);
return primeNum;
}
const result = isPrime(4);
console.log('4:', result)
But this is not a good idea - it's hard to read, and is not best practice. Better to use standard if/else statements instead.
Adding some brackets should to the trick, or your interpreter doesn't know what belongs to which expression.
Nested ternaries is not exactly best practices. Consider multiple if() return x;

Why won't my if/else statement work? (JavaScript)

I'm trying to code a script to test whether a user-inputted number is prime or not. I'm coding several different primality tests, but one in particular is giving me a hard time.
function isPrimeSix() {
var numberPrimeSix = document.getElementById("primeSixInput").value;
var loopCount = 0;
for (var i = 1; i < Math.floor((numberPrimeSix / 6) + 1) + 1; i++)
{
if (numberPrimeSix === (6 * i) + 1)
{
//Irrelevant code here//
}
else if (numberPrimeSix === (6 * i) - 1)
{
//More irrelevant code//
}
else
{
loopCount++
}
};
if (numberPrimeSix === 2 || numberPrimeSix === 3 || numberPrimeSix === 5 || numberPrimeSix === 7)
{
alert(numberPrimeSix + " is prime.");
}
else if (prime === false || loopCount === Math.floor((numberPrimeSix / 6) + 1))
{
alert(numberPrimeSix + " is not prime.");
}
else if (prime === true)
{
alert(numberPrimeSix + " is prime.");
}
else
{
alert("Error");
};
}
Every time the for loop goes around, the embedded if statement will not evaluate, even if for that particular value of i one of the statements is true. Regardless of what number is assigned to numberPrimeSix, the script will always go to the else section of the loop, meaning that an alert will pop up telling me that the number is not prime (because the value of loopCount is equal to the value defined by the last if statement).
Can anyone tell me why this is? I hope this makes sense, and if the 'irrelevant code' is needed I'll provide it. Thanks!
A string will never be exactly equal (===) to a number. In JavaScript, if you use ==, the operands will be converted to be the same type before comparing. If you instead use ===, that step will be skipped and instead they will be tested for strict equality, meaning same type and value, not just same value.
You have two options. Replace === with ==, or, convert the value before the loop and continue using strict equal. It will be much faster to convert the value before the loop so that you're not converting it over and over with each iteration.
var numberPrimeSix = parseInt(document.getElementById("primeSixInput").value, 10);
more reading: Which equals operator (== vs ===) should be used in JavaScript comparisons?

How to determine which value has a smaller index in an array

For a calculator I'm making I have an array with operators in which I need to know whether the times sign comes before or after the division sign. for this I had the following code (using JQuery's inArray):
if ($.inArray('*', operators) < $.inArray(':', operators)) {
//Multiplication is before division so perform mulitplication
}
else {
//Division is before multiplication so perform division
}
Now this code runs in a loop, and every time it removes the operator it has found from the array. This means that at some point there could be only multiplications in the array and no divisions. In the case the inArray function will return for example 3 for the multiplication, and -1 for the division. What you get:
if (3 < -1) ---> false
So it thinks it has found a division sign, where there is none.
It also has to work when it's the other way around: no mulitplication, but only division(s).
I can't come up with solutions to fix this, so that brought me here.
Why do you not use a hash which uses the operators (string) as keys and returns a precedence level (integer) as value?
Some operators have the same precedence level, like plus and minus.
Here is the precedence table for C++ operators, which is much more than you need, but should give you an idea.
One quick and dirty fix is to add an additional check for a '-1' return.
var divIndex = $.inArray(":", operators)
var multiIndex == $.inArray('*', operators)
if (divIndex != -1 && multiIndex < divIndex) {
// multiplication is before division
} else if (divIndex == -1 && multiIndex != -1) {
// only multiplication left
} else if (divIndex != -1 && divIndex < multiIndex) {
// division before multiplication
}
have you tried this?
if ($.inArray('*', operators) < $.inArray(':', operators) || $.inArray(':', operators < 0)) {
...
Test whether there's any division first:
if ($.inArray(':', operators) == -1 || $.inArray('*', operators) < $.inArray(':', operators)) {

Categories