My code contains a lot of multiple if
statements. Is there any other way to get rid of these statements. For example suppose I have the following conditions
if(t1 >= 1 && t2 == 0 && t3 == 0) $('div.b_class').fadeIn();
if(t1 == 0 && t2 >= 1 && t3 == 0) $('div.c_class').fadeIn();
if(t1 == 0 && t2 == 0 && t3 == 1) $('div.d_class').fadeIn();
if(t1 && t2 >= 1 && t3 == 0) $('div.b_class.c_class').fadeIn();
if(t1 && t3 >= 1&& t2 == 0) $('div.b_class.d_class').fadeIn();
Is there any way to simplify these statements?
You could use a switch case structure with conditions inside like this :
switch(true)
{
case (t1 >= 1 && t2 == 0 && t3 == 0) : $('div.b_class').fadeIn(); break;
case (t1 == 0 && t2 >= 1 && t3 == 0) : $('div.c_class').fadeIn(); break;
case (t1 == 0 && t2 == 0 && t3 == 1) : $('div.d_class').fadeIn(); break;
case (t1 && t2 >= 1 && t3 == 0) : $('div.b_class.c_class').fadeIn(); break;
case (t1 && t3 >= 1&& t2 == 0) : $('div.b_class.d_class').fadeIn(); break;
}
This should work:
var selector = 'div';
if (t1) {
selector += '.b_class';
}
if (t2) {
selector += '.c_class';
}
if (t3) {
selector += '.d_class';
}
$(selector).fadeIn();
It relies on the "truthy/falsy" values for tX (0 is falsy, 1-3 are truthy, see http://11heavens.com/falsy-and-truthy-in-javascript for further details on "truthy/falsy").
The only caveat to this approach is that it allows selector
to be 'div.b_class.c_class.d_class'
if t1
, t2
, and t3
are all non-zero.
If selector
is not acceptable in this case, change the t3
conditional to if (t3 && !(t1 || t2))
.
When the t3
conditional is modified to if (t3 && !(t1 || t2))
, the only way selector
can have d_class
appended is if t3
is non-zero and both t1
and t2
are zero.
var selector = 'div';
if (t1) {
selector += '.b_class';
}
if (t2) {
selector += '.c_class';
}
if (t3 && !(t1 || t2)) { //modified conditional
selector += '.d_class';
}
$(selector).fadeIn();
UPDATE:
The original answer was for what I suspected the OP actually intended (as the OP implies the code is hypothetical), so kudos to Juve for spotting that. To satisfy cbayram, this will duplicate the OP's logic (though I'm not sure if you could call this "simplified", as it only removes one if
comparison and is substantially more difficult to read).
var selector = 'div';
if ((((t1 && !(t2 || t3)) || (t1 && t3) || (t1 && t2 && !t3))) && !(t1 && t2 && t3)) {
selector += '.b_class';
}
if ((t2 && !(t1 || t3)) || (t1 && t2 && !t3)) {
selector += '.c_class';
}
if ((t3 === 1 && !(t1 || t2)) || (t1 && t3 && !t2)) {
selector += '.d_class';
}
if (selector === 'div') {
selector = '';
}
$(selector).fadeIn();
Here's a fiddle of it in action: http://jsfiddle.net/dX7AK/
OK, assuming you really have a lot of if
s and your t
s are fixed integers,
and the main goal is readability of your many, many "rules". Then you can try the following.
First I would make sure that all t
s have a valid value and skip the undefined cases.
If the variables t
are real logic values rather than numbers I would also use only
explicit rules (e.g., t1 == 0
instead of using >, <, >=, <=
), esp. if the rules you want to implement are as diverse as those expressed in your if
statements.
Then you could encode the logic using a numeric system, e.g., using decimals for good readability.
For each t
you use one decimal position of a the new "logic number" that encodes your logic:
111 means t1 == t2 == t1 == 1
201 means t1 == 2, t2 == 0, t3 == 1
etc.
The number is easily created from your t1
,t2
, and t3
:
num = t1*100 + t2*10 + t3
The switch-case below implements your logic. It is an unfolded version of your if
rules.
By not allowing for multi value checks (via >=
, etc.) we need to specify a rule for every
combination you want to handle. This might increase the number or rules you have to specify
but might also make your logic rules more readable and maintainable.
var getFadeInClass = function(t1,t2,t3) {
// for the sake of shortness I use ".b" instead of ".b_class" etc.
var num = t1*100 + t2*10 + t3
switch(logic_state){
case 100:; case 200:; case 300: return ".b"
case 10:; case 20:; case 30: return ".c"
case 1: return ".d"
case 110:; case 120:; case 130:;
case 210:; case 220:; case 230:;
case 310:; case 320:; case 330: return ".b.c"
case 101:; case 102:; case 103:;
case 201:; case 202:; case 203:;
case 301:; case 302:; case 303: return ".b.d"
}
return ""
}
You could also use Math or other kinds of test to reason on the numbers.
var x = t1*100 + t2*10 + t3
if ( x != 0 && x%100 == 0) return "b"
if ( x != 0 && x%100%10 == 0) return "c"
if ( x == 1 ) return "d"
But I would prefer the switch-case because it reads more nicely.
I hope this is what you wanted to achieve. :)
You can check out a running version of this decimal logic in this fiddle.
Cheers,
Juve
If t1, t2, and t3 are 0 to positive infinity, modified logic is a little condensed:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function orig(t1, t2, t3) {
var hits = "";
if(t1 >= 1 && t2 == 0 && t3 == 0) hits += 'div.b_class\n';
if(t1 == 0 && t2 >= 1 && t3 == 0) hits += 'div.c_class\n';
if(t1 == 0 && t2 == 0 && t3 == 1) hits += 'div.d_class\n';
if(t1 && t2 >= 1 && t3 == 0) hits += 'div.b_class.c_class\n';
if(t1 && t3 >= 1 && t2 == 0) hits += 'div.b_class.d_class\n';
return hits;
}
function modified(t1, t2, t3) {
var hits = "";
if(t2 >= 1 && t3 == 0)
hits += (t1 == 0)?'div.c_class\n':'div.b_class.c_class\n';
if(t1 >= 1 && t2 == 0)
hits += (t3 == 0)?'div.b_class\n':'div.b_class.d_class\n';
if(t1 == 0 && t2 == 0 && t3 == 1)
hits += 'div.d_class\n';
return hits;
}
function runTest() {
for(var i = 0; i < 3; i++) {
for(var j = 0; j < 3; j++) {
for(var k = 0; k < 3; k++) {
var o = orig(i, j, k);
var m = modified(i, j, k);
if(o != m)
console.info(o + " | " + m);
console.warn("t1="+i+", t2="+j+", t3="+k + ": " + ((o == m)?"PASS":"FAIL"));
}
}
}
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
In either case, this is a good way to test out your modification vs the original.