Reputation: 2053
Is there a better way to write conditional logic such as this?
if (dog == 'alive' && cat == 'alive')
...
elsif (dog != 'alive' && cat == 'alive')
...
elsif (dog == 'alive' && cat != 'alive')
...
elsif (dog != 'alive' && cat != 'alive')
...
end
If I were to add another animal, or another 4, things would get pretty out of hand. There must be a better way!
EDIT: My actual code has nothing to do with cats and dogs. I was just trying to keep it as general as possible. Not sure if this will affect the answers, but here you go. (It's Rails.)
if params[:search]
@requests = Request.search(params[:search], @cookies_city, @cookies_category).order('created_at DESC')
elsif cookies[:city_select]
if @cookies_city != "ALL" && @cookies_category != "ALL"
@requests = Request.all.where(:city => @cookies_city).where(:category => @cookies_category).order('created_at DESC')
elsif @cookies_city != "ALL" && @cookies_category == "ALL"
@requests = Request.all.where(:city => @cookies_city).order('created_at DESC')
elsif @cookies_city == "ALL" && @cookies_category != "ALL"
@requests = Request.all.where(:category => @cookies_category).order('created_at DESC')
elsif @cookies_city == "ALL" && @cookies_category == "ALL"
@requests = Request.all.order('created_at DESC')
end
elsif cookies[:category_select]
if @cookies_city != "ALL" && @cookies_category != "ALL"
@requests = Request.all.where(:city => @cookies_city).where(:category => @cookies_category).order('created_at DESC')
elsif @cookies_city != "ALL" && @cookies_category == "ALL"
@requests = Request.all.where(:city => @cookies_city).order('created_at DESC')
elsif @cookies_city == "ALL" && @cookies_category != "ALL"
@requests = Request.all.where(:category => @cookies_category).order('created_at DESC')
else
@requests = Request.all.order('created_at DESC')
end
end
end
Upvotes: 1
Views: 282
Reputation: 95354
Your original coding style is generally called a Decision Table (DT).
DT's are good, because it is easy to modify the conditions under which each action is taken easily.
When you hand code, they look big and clunky like you have. (Why do you care?)
One objection might be that the code isn't efficient (does it matter for your particular case?) because it re-evaluates the sub-conditions repeatedly. That may or may not be true; its your compiler's optimizing ability that decides that; a good compiler can pick out useful subexpressions and evaluate a small set.
For performance, one might want to have a decision tree. The good news is they are fast; the bad news is they are hard to update. If you insist on a decision tree, it is best you write your tests as a decision table for maintainability, and let some tool convert the conditions into the decision tree for you. Then you end up with a maintainable result, and fast performance.
Upvotes: 1
Reputation: 40336
If you can structure your code so that you return from each branch, it can be a lot cleaner. Sometimes this may entail extracting a method. And ternary operators, if your language supports them, can make matters clearer if used judiciously
if (dog == 'alive')
return cat == 'alive' ? 'bothLiving' : 'justDog';
return cat == 'alive' ? 'justCat' : 'bothDead';
Upvotes: 1
Reputation: 952
First you should derive all those from a common class like
public class Animal {public bool Alive{get; set;}}
.
put them all in a 'List'
then run them through 2 for loops (pseudo code)
for(int x = 0;x < animals.Count;x++)
{
for(int y = 0;y < animals.Count;y++)
{
if(animals[x].Alive == animals[y].Alive)....
}
}
sorry but that's as far as can could go with this answer since you are looking for a means without an end
I am not really sure how you would collect and use the data of comparing each animals alive status to each others but this should get you started
and if you don't want to compare the same animals just test if x and y are the same
Upvotes: 0
Reputation: 81
You may use different bits to represent animal's state (alive or dead). Then it's a simple switch statement like
switch (state) {
case 0: // None alive
...
break;
case 1: // 0th bit alive only(say dog)
...
break;
case 2: // 1st bit alive only (say cat)
....
break;
case 3: // 0th and 1st bit alive (dog and cat)
}
And when you want to add more just use next bit and add 'case' inside switch statement.
Upvotes: 1