Multiple OR conditions for an IF statement - javascript

Am I doing the multiple OR conditions for an IF statement the right way?
var A0minWidth = 841;
var A0minHeight = 1189;
var A0minWidthBleed = 847;
var A0minHeightBleed = 1195;
UploadedDocNameHeightMM = //(get it from the database)
UploadedDocNameWidthMM = //(get it from the database)
if(UploadedDocNameHeightMM < parseFloat(A0minHeight) || UploadedDocNameWidthMM < parseFloat(A0minWidth) || UploadedDocNameWidthMM > parseFloat(A0minWidthBleed) || UploadedDocNameHeightMM > parseFloat(A0minHeightBleed))
{
//do this
alert ("Yes! one of those.")
}
Help!

It depends on what your code is supposed to do of course, but syntactically this is correct - e.g. no need to wrap each each expression that is an operand to the logical-OR operators in parentheses like this:
if ((UploadedDocNameHeightMM < parseFloat(A0minHeight)) || (UploadedDocNameWidthMM < parseFloat(A0minWidth)) || (UploadedDocNameWidthMM > parseFloat(A0minWidthBleed)) || (UploadedDocNameHeightMM > parseFloat(A0minHeightBleed)))
{
alert("Yes! one of those.");
}
Also, the || operator will short-circuit evaluate. Basically it will not evaluate expressions to the right of any expression that evaluates to true.
For more information on || and other JavaScript logical operators including examples check out Mozilla's overview or search on JavaScript logical operators.

The syntax is correct.
However:
parseFloat is not necessary here
Are you sure the two first tests are correct (==> Don't you need to check if UploadedDocNameHeightMM > A0minHeight instead of < ?)

Related

Javascript parser for logical expressions

I have expression like 5+10 > 4+1 or (3+10 < 5+1)
i need to evaluate this expression to return true or false
is there any JavaScript libraries that can help me in that
You don't need library. Just:
var s = (5+10 > 4+1) || (3+10 < 5+1); //s is true

unexpected results in evaluation of chains logical expressions javascript

I am writing a program to identify special numbers according to the criteria laid out in this code wars kata:
http://www.codewars.com/kata/catching-car-mileage-numbers
Here is a link to my full code and tests:
http://www.codeshare.io/UeXhW
I have unit tested my functions which test for each of the special number conditions and they appear to be working as expected. However, I have a function:
function allTests(number, awesomePhrases){
var num = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros(num) || sameDigits(num) || incrementing(num) || decrementing(num) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
which determines if any of the criteria of being a special number is met and that's not working as expected. For example, when I tested the allZeros() function on 7000 it returned true, but alltests(7000) is returning false. Is there something about how chains of logical expressions are evaluated that I don't understand or is the problem something else?
I have looked at W3schools and MDN to try and diagnose the problem.
Change all your !== to != will do.
False results as long as allTests() executes with a second argument even it it's the empty string, as follows:
allTests(7000,"");
If the function is called with just one argument, i.e. the number, expect this error:
Uncaught TypeError: Cannot read property 'length' of undefined
The error message refers to one of the functions in the logic chain, namely matchPhrase() which expects two parameters: number and awesomePhrases. If instead of providing an empty string, you use null, you'll also get the same error message.
JavaScript doesn't support the concept of default parameters -- at least not in a way that one might expect; the parameters default to undefined. But there is a way to work around this hurdle and improve the code so that one may avoid this needless error. Just change matchPhrase() as follows:
function matchPhrase(number, awesomePhrases){
awesomePhrases = typeof awesomePhrases !== 'undefined' ? awesomePhrases : "";
for(var i = 0, max=awesomePhrases.length; i < max; i++){
if(number == awesomePhrases[i]){
return true;
}
}
return false;
}
The first statement accepts the second argument's value as long as it is not the undefined value; if so, then the variable gets set to the empty string. (Source for technique: here).
To make the code more readily comprehensible, I suggest rewriting allTests() as follows, so that the code follows a more explicit self-documenting style:
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros( arrDigits ) || sameDigits( arrDigits ) || incrementing( arrDigits ) || decrementing( arrDigits) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
This function takes a number and uses its toString() method to convert the number to a string. The resulting string which is not visible will split itself on the empty string so that the result of arrDigits is an array of numerical strings, each one consisting of just one digit. This is the point of origin for the ensuing problem with allZeros() which compares a stringified digit with a number.
Incidentally, in the function allTests() there is an awfully lengthy ternary expression. The syntax is fine, but you might wish to rewrite the code as follows:
function getCriteriaStatus(arrDigits,number,awesomePhrases) {
var criteria = new Array();
criteria[0] = allZeros( arrDigits );
criteria[1] = sameDigits( arrDigits );
criteria[2] = incrementing( arrDigits );
criteria[3] = decrementing( arrDigits);
criteria[4] = palindrome(number);
criteria[5] = matchPhrase(number, awesomePhrases);
var retval = false;
for (var i=0, max=6; i < max; i++) {
if ( criteria[i] == true ) {
retval = true;
break;
}
}
return retval;
}
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
var criteria_met = getCriteriaStatus(arrDigits,number,awesomePhrases);
return (number > 99 && criteria_met);
}
To obtain the desired true result from allTests() when it invokes allZeros(), rather than complicate the code by using parseInt(), I suggest rewriting allZeros() and any other functions containing code that compares a numerical string value with a number by changing from the identity operator to the equality operator. The change involves merely replacing === with == as well as replacing !== with !=. The code that compares values of the same data type, using the identity operators, those operators may, and probably should, remain unchanged. (See here).

Lost in javascript comparisons

I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators

Using multiple logical "or" operators

Other than using a switch statement (or writing if(x === 2 || x === 3 || x === 4) etc), is there any way to implement multiple "or" (||) operators?
E.g.:
if(x === 2 || 3)
alert("Yes");
This alerts for every value of x
The closest you can probably come is to do something like this:
if ([2,3].indexOf(x) > -1){
}
DOCS
Of course that will require a shim for IE 8 and below, if that's an issue for you.
Standard approach for large number of choices is to use dictionary/hash set/hash table depending on language.
For JavaScript both array and object would work:
var isPresent = [];
isPresent[2] = true;
isPresent[43] = true;
if (isPresent[x])...
For small number of items Adam Rackis' answer with linear search is much more readable
[2,3].indexOf(x)

An explanation of && shorthand in JavaScript

Using a watermark plugin for jQuery, I'm attempting to jslint and minimize the functions but I've come across syntax I have never seen before wherein there are expressions where there really ought to be an assignment or function call:
(function($) {
$.fn.watermark = function(css, text) {
return this.each(function() {
var i = $(this), w;
i.focus(function() {
w && !(w=0) && i.removeClass(css).data('w',0).val('');
})
.blur(function() {
!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
})
.closest('form').submit(function() {
w && i.val('');
});
i.blur();
});
};
$.fn.removeWatermark = function() {
return this.each(function() {
$(this).data('w') && $(this).val('');
});
};
})(jQuery);
I'm specifically interested in the following lines:
w && !(w=0) && i.removeClass(css).data('w',0).val('');
and
!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
Can someone explain this shorthand and rewrite these functions in such a way that I could compare them to better to understand the shorthand myself?
Thank you.
Let's break each of the statements you're asking about down to their components:
w && !(w=0) && i.removeClass(css).data('w',0).val('');
w - Is w "true"? (checking for != 0 in this case)
!(w=0) - Set w to 0, take the opposite of the result so the && chain continues
i.removeClass(css).data('w',0).val('') - Remove the class, set the data to 0 clear the value.
!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
!i.val() - Is the input empty?
(w=1) - Set w to 1
i.addClass(css).data('w',1).val(text); - Add the class, set the data to 1 and set the text to whatever the watermark text is.
Both of these are just statements to really cut down on code, certainly at the expense of readability. If you're looking at a de-minified version this is very common, if you're not and this is the original, chase the author with a salad fork, the original should be more more readable than this IMO, though it's just fine for a minified version.
&& can be used as a "guard." Basically it means stop evaluating the expression if one of the operands returns a "falsy" value.
Negating an expression will convert it to a boolean value. Specifically one that is a negation of the expression depending on whether it's 'truthy' or 'falsy'.
w && !(w=0) && i.removeClass(css).data('w',0).val('');
Basically says:
w is "truthy" (defined, true, a string, etc.)
AND set w to zero + convert the expression to true (because (w=0) would evaluate to 0, which is falsy)
AND evaluate i.removeClass(css).data('w',0).val('')
These can be rewritten as:
// w && !(w=0) && i.removeClass(css).data('w',0).val('');
if (w) {
if (!(w=0)) {
i.removeClass(css).data('w',0).val('');
}
}
//!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
if (!i.val()) {
if (w=1) {
i.addClass(css).data('w',1).val(text);
}
}
Using && like this is just a shorthand for using nested ifs. It's advantages being:
Uses marginally fewer characters than the exploded nested ifs, decreasing the payload that's delivered to the browser.
Can be faster to read for the trained eye.
Though, I must say that the above examples are an abuse of this shorthand because the conditionals used are fairly complex. I only resort to this shorthand when I need to check a chain of simple things like in the following example:
function log(s) {
window.console && console.log && console.log(s);
}
&& is And. It's for comparison / compound conditional statements. It requires that both conditions in an if statement be true. I do not think there is another way to rewrite it - that is the syntax for And.
With respect to:
w && !(w=0) && i.removeClass(css).data('w',0).val('');
the code:
!(w=0) && i.removeClass(css).data('w',0).val('');
will only execute if
w
is truthy.
Using
w && !(w=0) && i.removeClass(css).data('w',0).val('');
for this explanation, it allows you to string multiple commands together while ensuring that each is true.
This could also be represented by:
if (w) {
w = 0;
i.removeClass(css).data('w',0).val('');
}
It first makes sure w evaluates to true, and if it is, it checks if w=0 is not true (w != 0). If this is also true, then it goes on to the actual command.
This is common shorthand in a lot of languages that use lazy evaluation: If the next evaluation is put in with and (&&) then the following commands will not be executed if it returns false. This is useful in the sort of situations where you only want to perform an action on something if the previous statement returns true, like:
if (object != null && object.property == true)
to make sure object isn't null before using it, otherwise you would be accessing a null pointer.

Categories

Resources