Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am curious as to if I am using too many if/else if statements.
I am writing a tic-tac-toe program using javascript, and to determine if the computer should block the player I am using about 9 if statements and I use about 9 when determining if there is 3 in a row.
For example:
if(r1c1V === xOrO && r1c2V === xOrO && r1c3V === xOrO)
{
is3InARow = true;
}
else if(r2c1V === xOrO && r2c2V === xOrO && r2c3V === xOrO)
{
is3InARow = true;
}
else if(r3c1V === xOrO && r3c2V === xOrO && r3c3V === xOrO)
{
is3InARow = true;
}
.
.
.
.
and so on.
So my question is, am I using too many if statements? or is there no better way to do this?
My friend was telling me that I shouldn't really use that many if statements, but I am not sure if he is true or not, I can understand why in some cases that it would be slower or bad, but I am not sure.
Thanks in advance!!
This is rather subjective, so is not really ideal for Stack Overflow.
What your friend is probably suggesting is that programs which use long if/else statements, nested ifs etc. are sometimes difficult to maintain, and are not always very readable. You can sometimes replace long if statements with a separate function, which can be much easier to maintain.
For instance in tic-tac-toe:
function checkRow(rowToCheck){
if (rowToCheck[0] === rowToCheck[1] && rowToCheck[1] === rowToCheck[2]){
return true;
} else {
return false;
}
}
Not to say that is perfect or even good code, but you can see how it would allow you to reduce the number of if statements in your code. It could be factored further:
function checkRow(rowToCheck){
var allMatch = true;
for (var i=0;i<rowToCheck.length && allMatch;i++){
allMatch = rowToCheck[i] === rowToCheck[0];
}
return allMatch;
}
That allows for rows of varying length, and cuts down of the if statements. Anyway I hope that explains some of the ways you can remove if statements.
Edit
Further in the future, I'd suggest that there is yet another, better way to check the equality of the elements in a row:
const o = 'o'
const x = 'x'
const rows = [
[o, x, x],
[x, x, x],
[o, o, x]
]
const rowIsEqual = row => !row
.some(square => square !== row[0])
const results = rows.map(rowIsEqual)
console.dir(results)
Programming is all about automating processes. You will not hear me say that the way you are doing this is wrong. If it works then it is oke. But of course it would be more beautiful if you could find a way to make it check everything automatically. Like looping through all x cords and just check if all of those are checked. This may not be easier, but it will be more extendable. If you'd ever wish to play a game on a ten by ten grid. then you would only have to say that that is the size of the field. Right now you would need to add all those other lines of code.
In general, yes, "too many" ifs are bad. Any problem can be solved just using ifs, but everything you see around you, functional programming, recursion, object modelling, is there to stop the if's getting out of control and leaving you with sprawling incomprehensible code. You should be more worried about the depth of nested ifs than the length of a sequence. Here's tic-tac-toe on rosetta code, if you want to see real cleverness.
There's no hard-and-fast rule. Do bear in mind that && and || are short-circutted meaning that evaluation stops once the result is known. That and the fact that you are able to order the if statements in any way you please means that you can optimise things by considering frequent comparisons first.
Always do what's clearest, and if performance is crucial, what's fastest.
So many apps are built with long if then else statements? Why? Wouldn't a dictionary be better? Look up the keyword and perform the associated action. I'm surprised I can't find a simple python library that does this for multiple back-ends including databases.
I guess using too many if- else statements decrease the readability of the program.You can use switch-case statement instead of using if-else statements.Just google switch-case in javascript and you will get many useful links to get an idea about it.
In your scenario, its not bad at all.
You can add return on your code if it can so that it won't execute other condition... JUST if its possible on your scenario.
In these cases we use 'Recursion'.
To answer your question; if you use to many if statements you are doing something wrong. You can use other methods to get the to goal you want.
Example:
you got a grid of 2,2 (0,1,2 and 0,1,2). So what you should do is create a algorithm that calculates the score. A very popular one is MiniMax.
Related
I am working on a question for my Computer Programming class in high school and the question is as follows.
Using a conditional statement, generate a program in any coding language and explain the working of it: “If the temperature of your room is more than 80° or less than or equal to 60°, then the program should branch; otherwise, the execution should continue without branching.”
I have managed to create a conditional statement on my own, but I do not understand the branching part. I have Googled already and have found nothing useful. Can someone explain what I am supposed to do?
**Also, I chose JavaScript for my coding language.
function temperature(z) {
if(z > 80 || z <= 60) {
/*branch program?*/;
}
else {
/*do not branch program?*/;
}
}
console.log(temperature(81)); /*evaluates to branching*/
That is all I have so far. Also, is there a simpler way to write that code? I would love some opinions!
The if statement itself is a branching instruction to your CPU where in assembly language CPU would’ve taken that instruction as a possibility to skip set of instructions inside the if statement and continue after it (branching) or execute that piece of code within the normal flow.
I believe that the statement you wrote is already a perfect example of the question, you should just be able to change some variable inside that if where that exact variable would’ve taken different value if the program were to take different execution path (aka branch).
Edit:
You could end up with code looking something like this:
function getTemperatureFeel(t) {
var feel = "Perfect"; // this is straight execution
if (t > 80 || t <= 60) {
feel = "Either warm or cold"; // this is branch execution
}
return feel;
}
console.log(getTemperatureFeel(81));
I'm making a bot for a gaming chatroom with some friends, but I've hit an impasse. Is there a reliable way to get numbers from inside a string of text that won't completely break an inexperienced script kiddy's brain? Here's the best I've been able to come up with so far, variables simplified slightly for illustration's sake:
var k = [0];
function dieRoll(m,n) {
for(i = 0; i < m; i++) {
k[i] = Math.floor(Math.random()*n)+1;
}
}
var m = text[5];
var n = text[7];
if (text === 'roll '+m+'d'+n) {
dieRoll(m,n)
console.log(k);
}
The biggest problem as-is is that it's limited to single-digit input.
EDIT: Looping through the text looking for integers is exactly the kind of thing I'm looking for. I don't have much experience with programming, so I probably tend to end up with overly complicated and confusing messes of spaghetti code that would embarrass anyone remotely professional. As for the format of the input I'm looking for, "roll [number of dice]d[highest number on the dice]". For anyone who doesn't know, it's the notation most tabletop rpgs use. For example, "roll 2d6" for two normal six-sided dice.
EDIT: It's not that I'm necessarily against regex, I just want to be able to understand what's going on, so that if and when I need to edit or reuse the code it I can do so without going completely insane.
EDIT: Thank you all very much! split() seems to be exactly what I was looking for! It'll probably take some trial and error, but I think I'll be able to get her working how she's supposed to this weekend (Yes I call my bots 'she').
Basically, you need to look at the format of the input you're using, and identify certain facts about it. Here are the assumptions I've taken based on your question.
1) The "roll" command comes first followed by a space, and
2) After the command, you are provided with dice information in the form xdy.
Here's something that should work given those constraints:
function getRollParameters(inputCommand) {
var inputWords = inputCommand.split(' '); //Split our input around the space, into an array containing the text before and after the space as two separate elements.
var diceInfo = inputWords[1]; //Store the second element as "diceInfo"
var diceDetails = diceInfo.split('d'); //Split this diceInfo into two sections, that before and after the "d" - ie, the number of dice, and the sides.
//assign each part of the dicedetails to an appropriate variable
var dice = diceDetails[0];
var sides = diceDetails[1];
//return our two pieces of information as a convenient object.
return {
"dice": dice,
"sides": sides
};
}
//a couple of demonstrations
console.log(getRollParameters("roll 5d8"));
console.log(getRollParameters("roll 126d2"));
Effectively, we're first splitting the string into the "command", and the "arguments" - the information we want. Then, we split our arguments up using the "d" as a midpoint. That gives us two numbers - the one before and the one after the d. Then we assign those values to variables, and can use them however we like.
This obviously won't deal with more creative or flexible inputs, and isn't tested beyond the examples shown but it should be a decent starting point.
I'm pretty new here but i'm posting this cause i haven't found a single answer on the internet to this question.
How can I use multiple arrays as conditions to an if statement. the reason i would need this is simply for creating a 2D game. But i'm learning that even a simple 2D game has tons of variables because of all the objects involved. But here is a simple example for what I've started with.
var a = 27;
var test = 0;
if(a in {18:1, 27:1, 36:1}) {
test = 1;
}
This tests an array of variables against one variable. I've found that this returns true but this is only half the battle.
The only place I've found any close reference to this is here.
How to shorten my conditional statements
Now the hard part is getting two arrays as conditions instead of just a variable and an array. So basically i need this idea made shorter.
var a = 27;
var b = 27;
var c = 50;
var test = 0;
if(a in {18:1, 27:1, 36:1} || b in {18:1, 27:1, 36:1} || c in {18:1, 27:1, 36:1}) {
test = 1;
}
even though i'm a noob my bible is the hacker's standard:P. Which basically means i think that when i'm creating something with the process of doing something over and over without very good reason "IT IS THE DEVIL"(kudos to whoever got the references). So let me explain this again but very specific so there's no confusion. Say i create a lot of NPC(non player character) and i want a system that can detect if the individual NPC has been in contact by lets say a projectile. i want that individual to vanish and give a point to a score board. well creating functions for such characters requires a LOT of if statements. So ideally i want an if statement that somehow uses 2 or more arrays for it's conditions but look almost as short as using two variables.
maybe something that looks like this.
var test = 0;
var a = [5,6,8];
var b = [10,30,8];
if(a in b){
test = 1;
}
NOTE: I've actually already tried this but it only took the index of b and not the numbers inside. I believe this topic deserves attention unless there's already someone out there that posted a solution(in which case it NEEDS to be advertised).
EDIT: After a long while i've come to realize that the proper(more efficient and readable) solution is to use both OOP and game engine design. I was just too young to understand how to work with data. So to anyone who see's this wondering the same thing should simply try to more thoroughly study array and class logic. In honesty javascript is NOT the place to learn this. I recommending taking a trip to processing.org. and learning the ways of using classes. if Your having trouble there you can try openFrameworks and learn OOP in c++. But the biggest part is understanding proper array mechanics. The OOP just makes it easier.
var test = false;
var a = [5, 6, 8];
var b = { 10:1, 30:1, 8:1 };
for (var i = 0; i < a.length; i++) {
if (a[i] in b) {
test = true;
break;
}
}
If you're using a library like jQuery or Underscore.js, they have convenience functions like $.any() that can be used to replace the loop. You can also use the built-in Array#some method, but it's not compatible with IE8. Ex:
return a.some(function(x) {
return x in b;
});
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
I would like to avoid unresponsive javascript in all browsers.
Is it possible to write code with that in mind?
DETAILS: Problem is that currently there is a potential script block that executes fine in Chrome on my PC, but causing problems on IE (various versions). The worst thing is that I really don't know for sure if it is that script block at all. I will rewrite and solve that. However, I would like to know what exactly I should be avoiding while coding. This...
http://www.sitepoint.com/javascript-execution-browser-limits/
...is an interesting read but it's too general.
EDIT: I'm using jQuery/jQueryUI as well.
EDIT 2: There are patterns/principles to use to avoid particular problems. E.g. singleton pattern, PRG pattern, DRY principle... and such. Is there something like that for this kind of problem?
I've run into problems like this before as well.
The thing to keep in mind as you code, is where does my code begin execution, and where does my code end execution. For all of the time between those two points, the browser's UI thread is blocked, and the browser makers have understandably developed counter measures.
As far as what to avoid, avoid long, continuous loops.
Here's an extreme example:
function howManyMultiplesOfFourBelow(foo) {
var i = 0, j = 0;
while (i < foo) {
i++;
if (i % 4 === 0) {
j++;
}
}
return j;
}
If you pass 10,000,000 to that function, IE will definitely throw a fit. There is more than one way to program around this kind of situation; what I prefer is to break up the code using setTimeout/setInterval. After setting an interval and returning out of a function, we release the UI thread back to the browser, and the browser is in charge of executing the interval as often as we've requested (or as often as it is able).
I combine this with Futures/Promises; In particular, jQuery's implementation.
Using this style, the above example could be rewritten not to block the UI thread during the calculation by leveraging promises, and setInterval.
function howManyMultiplesOfFourBelow(foo) {
var deferred = $.Deferred(),
interval,
i = 0,
j = 0;
interval = setInterval(function () {
if (i >= foo) {
clearInterval(interval);
deferred.resolve(j);
return;
}
i++;
if (i % 4 === 0) {
j++;
}
}, 1);
return deferred.promise();
}
The first important difference is that this function no longer returns the answer, but instead a promise of an answer. So, consuming code might look like this:
howManyMultiplesOfFourBelow(10000000).done(function (multiples) {
//Update the DOM with the answer (multiples)
});
Returning to your question more generally, think about how much of your code must be run continuously, and if any of it could be delayed, or broken up in order to release the UI thread briefly.
I would like to edit my if else statement in javascript dynamically.
So after one if statement is used, it could be removed. I get this maybe isn't possible but after a search online failed, my curiosity begged me to ask.
For instance:
if (x > 200 && x % 25 === 0) {
doSomething1();
} else if (x > 300 && !inRange) {
doSomething2();
} else if (x > 400 && x % 7 === 0) {
doSomething3();
}
There are eight if else statements within this loop. The loop determines which object to create. There are 2000 objects created over the course of a couple minutes. If on average we reach the fourth statement before it breaks, then there are 8,000 calculations being performed just within this one set of statements.
I want to streamline the script for speed and again, curiosity if we can actually write javascript dynamically without using separate functions etc. After an if statement fails, it is often not required anymore. The next statement could I suppose, include code to remove its predecessor dynamically. This might save 3 or 4 thousand calculations - not huge I know, but worthy of consideration given that there are lots of other things going on as well.
Is there a way to remove them dynamically or does anyone have any tricks or patterns up their sleeves?
Also, even if this is not available in js, what would this be called?
No. And the need for such would indicate poor design.
You should use a conditional expression to determine when which code segment should be run, as you mention. If you pass a certain threshold within your code after which you no longer want a condition to be executed in your loop, why not simply break the loop and have a new code block handling the doSomethingElse clause. If you're using setInterval, that's the point at which you would call clearInterval, and then trigger some new action if necessary. Anyway, running a single (or even a few) simple conditional statement doesn't add much overhead, and isn't likely to be the limiting factor in your optimization anyway.
Ignoring the fact that I doubt this is a bottleneck in modern browsers that JIT the JavaScript (CPUs are very good at predictive branching) as shown because simple number comparison is not going to be expensive even in large iterations with smart predictions once it's compiled.
You can do this by injecting a different function:
checker: function(x) {
if (x > 200) {
doSomething1();
}
else if (x > 300) {
doSomething2();
}
else if (y > 400) {
doSomething3();
}
}
Can be changed to
checker: function(x) {
if (x > 200) {
doSomething1();
}
else if (x > 300) {
doSomething2();
this.checker = smallerChecker;
}
else if (y > 400) {
doSomething3();
}
}
function smallerChecker(x) {
if (x > 200) {
doSomething1();
}
else if (y > 400) {
doSomething3();
}
}
Fundamentally, you simply need to make the behavior injectable, and then you change it however you see fit. Be-it by replacing the function doing the checking outright (the functional way) as I did above, or enabling an object to replace it (the OO way).
Why would you want to remove them dynamically? Altering the code dynamically is unnecessary and a bag of worms that's overdoing it for this situation. You should be using a flag.
I'll answer separately for whether you're trying to skip a large group of if statements, or an individual if statement.
Foreword
As mentioned in the comments on your question, run profiling to make sure you know where your performance problems are!
You mention your aversion to simply using boolean flags to make an if statement not run in your answer. This is fine, and it's what people normally do. This should not be an actual performance concern, and profiling will probably show your performance problems lie elsewhere. If they don't and this boolean flag check is genuinely your bottleneck - you have bigger problems, such as expecting too much from your JavaScript code, or that you didn't use the profiling tool correctly, or misinterpreted its results.
If you're trying to avoid running the body of an if statement, or its conditions, those are a bigger performance concern to you than the boolean flag check itself.
For skipping a large group of if statements
Wrap your bunch of if statements in a condition.
if (runBunchOfIfStatements) {
// all those if statements here
}
When you're past the point of wanting those if statements to run, set the runBunchOfIfStatements flag to false (of course, you should probably pick a more meaningful name than that).
That said, 8 or 9 if statements is a code length issue, and more than likely means nothing at all for performance concerns - unless those if statements happen to involve very intensive checks. If you're worried just because there's a lot of if checks, you're probably looking in the wrong place.
For individual if statements
Say you have only one if statement you want to skip. You had this code in your answer:
} else if (x > 300 && !doneSomething2) {
doSomething2();
doneSomething2 = 1;
}
This is fine. You're just making a tiny check: see the foreword. Look elsewhere for your performance concern. It could be rewritten slightly to more closely follow convention (which I'm about to get to), but in this situation, the change will have negligible impact.
Let's take a situation where there is actually a performance concern here. Suppose that instead of checking x > 300 you're doing something more intensive like calculateSeveralSquareRoots(). Generally, you do take this approach, but you rearrange it like this:
} else if (needCalculations && calculateSeveralSquareRoots() {
// do stuff
needCalculations = false;
}
The difference here is the needCalculations flag comes first, not second. JavaScript's comparison operators have short circuit evaluation. This means that when evaluating a && b, if a is false, b never even gets checked - we already know the result will be false. If the flag comes first, that means calculateSeveralSquareRoots() never gets run, and you save time on the check.
If the flag came second, then you're potentially wasting a lot of time on that function for a condition that might almost always resolve to false anyway thanks to that flag.
So in your original, you could have the flag come before the x > 300 evaluation, just to follow convention. But again... if an if statement like this is a real and significant performance concern for you, then you have bigger issues.
Order them in order of likelihood (so if >400 is most common, check for that first, and if x<200 is next most common, check for that, etc.) The example code is in order of increasing boundaries.
Next, your code doesn't show it and you just imply it, this is in a loop. (And if it isn't a loop, then this isn't a perf issue of interest) You could try fancy loops like Duff's device.
And figuring out what code can be changed to use more native API's is going to make a magical difference, whereas code optimizations like this will likely make only a marginal difference.
If you want it to be dynamic, you could always have a collection of conditions associated with actions and as soon as executed, these gets removed from the collection. However, I doubt it will lead to faster code execution, but you would have to create a jsperf test to know for sure.
DEMO: http://jsfiddle.net/a2ZEj/1/
function doSomethingA() {}
function doSomethingB() {}
var doOperation = (function doOperation() {
var operations = [
{
check: function (someArg) {
return someArg > 100;
},
exec: doSomethingA
},
{
check: function (someArg) {
return someArg > 100 && someArg < 200;
},
exec: doSomethingB
}
];
return function (someArg) {
var i = 0,
len = operations.length,
item;
for (; i < len; i++) {
if ((item = operations[i]).check(someArg)) {
item.exec();
operations.splice(i, 1);
console.log('executed ' + item.exec.name);
return;
}
}
};
})();
doOperation(101); //calls doSomethingA
doOperation(101); //calls doSomethingB
doOperation(101); //does nothing
You can create a method as below and create dynamic conditions
function buildCond(lhv1,rhv1,lhv2,rhv2)
{
var condition1,condition2;
condition1 = condition2 = '';
if(rhv1 !== -1){
condition1 = lhv1 + " == " + rhv1 + " && ";
}
if(rhv2 !== -1){
condition2 = lhv2 + " == " + rhv2 + " && ";
}
return condition1 + condition2;
}
And then call this method with eval to execute
if(eval(buildCond(var1,value1,var2,value2)) === true){
//do stuff
}