• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Bear Bibeault
  • Liutauras Vilda
  • Devaka Cooray
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • Henry Wong
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • Tim Holloway
Bartenders:
  • salvin francis
  • Frits Walraven
  • Piet Souris

Too many possible combinations of if/else and conditional statements. How do you shorten?

 
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was trying to make something where people add data samples from a survey, and they can search it.  Something for a summer camp.

For example, they want to query by ages 8 and 9, and boys.  They have the option to filter or not to filter by a given category.  There is a radio button selected where they choose all results of a category, or to filter them.  

If it was just those two criteria, it would look something like this...



Then, I would do one where the other is true and other false, and both false.  

This works if it is only two criteria, but I have eight, which means there will be close to 100 statements if I do it this way.  

They may choose to filter all of them, they may choose none of them,  they may choose a combination of some of the eight, so I can't make an if statement for all of them.  

They basically will want to know who answered how in the survey based on a given criteria, but it could be any combination they choose to filter.  


The only other way I thought is if you just make an ArrayList of all the results, and if(true) statement for each filter, and then remove the samples from the ArrayList if they don't meet the filtered criteria for that given if statement until you are down to the last statement.  

Is that the best way to do it?
 
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Start by getting rid of the == true and == false everywhere. They are both poor style error‑prone because one day you will write = instead of ==.
Write down in very simple terms what your code is supposed to do. No computing terms. Explain what each combination is supposed to mean. Explain how a boolean genderIsFiltered is going to find you boys.
 
Rancher
Posts: 858
20
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generally speaking, you use a "switch" statement.
 
Nathan Milota
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Switch doesn't allow boolean.
 
Nathan Milota
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:. . . Explain what each combination is supposed to mean. . . . .



So, there's 8 different sets of criteria they can choose to filter out based on.  If they select the radio button to filter based on gender, it will make it true, then they can select only boys to see how they responded to the survey.  

However, they may choose to filter 7 of the 8 criteria, or 6, etc.

I can't make that many statements.  
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That isn't a complete explanation of what you want. Only a partial explanation.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please don't quote the whole of a previous post, which simply duplicates writing without adding new information. See this link, and as it says there, I have removed most of the quotes.
 
Ranch Hand
Posts: 82
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you are doing just filtering by chosen filters/attributes, then I don't see applicability in following code snippet:



Because in such scenario, you don't care about false values/not chosen filters/attributes as you simply don't filter by them... You should only care about each filter  == true in isolation. If you're doing specific logic based on concrete combinations then never mind, but I just want to make sure, since it isn't exactly clear from your explanation...
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Nathan Milota wrote:. . . radio button . . .

That is a computing term which presumes I know more about your app than I actually do. It is also an implementation detail which obscures the intent of the app with how you intend to do it.
Remember that a GUI is always subordinate to the app. Design the app first then write a GUI to make it easier to use.
 
Nathan Milota
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I didn't think it was all that difficult to understand, but I must not be explaining it correctly.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Miroslav Lehotsky wrote:. . . you don't care about false values/not chosen filters/attributes as you simply don't filter by them. . . .

Exactly. There are ways to filter by multiple attributes; I can think of two “just like that.” Neither would use multiple if‑elses, nor a switch‑case.
 
Les Morgan
Rancher
Posts: 858
20
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nathan,

Use binary flags.  If your search criteria are predefined as you imply from your problem statements, then binary flags make your task very simple.

Each of your criteria becomes a bit mask in your flag:

Condition 1 is given a weight of 2^0 (0, 1)
Condition 2 is given a weight of 2^1 (0, 2)
Condition 3 is given a weight of 2^2 (0, 4)
and etc...

This requires you prequalify each record with its qualifying conditions in its own binary flags. So if, for example, a record qualifies on conditionn 1 and 3 only, then you have 2^0+2^2 or a mask of 5, binary representation would be 00000101, if you have 8 total.

You build your form allowing the user to choose their filter criteria and build a binary mask with the same weights. You simply bit wise AND the two masks and the compare the result to the user generated mask



This easily allows narrowing of the selection by literally relooping through the user criteria selection time and time again.

You have to also account for exclusivity where only the criteria trigger and any that contain this.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That would work, but it looks like a very low‑level solution to me.
 
Nathan Milota
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I was just thinking about this all wrong.  

I realize you don't consider the ones not true, but how many are true could be a different number and a different combination of them each time.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Les Morgan wrote:. . .. . . .

You can reduce that to a switchStill low‑level. You can improve its style by writing the numbers in hex or binary. This style would be even better:-But it is still low‑level code, and will probably lead to a great deal of code repetition.
Have you considered if ((userMask & recordMask) != 0) ... But it is still low‑level code. The inner () are necessary to get the code to compile.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Nathan Milota wrote:I think I was just thinking about this all wrong. . . .

That is where a proper explanation of what you are going to do will help.
 
Bartender
Posts: 3747
154
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A way to simplify Les' proposal is to make use of the Predicate.and method. Suppose that all chosen filters are combined via 'and'. Then you can do a procedure like this:

So i the end you simply get:

Mind you that this sounds easier than it is. If you want to filter on age, for instance, then you have at least two extra onditions: filer on what age, and should it below or above? So, setting up such a filter for more than one criterium is quite laborius.
 
Nathan Milota
Ranch Hand
Posts: 350
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The switch won't work, as it breaks the entire switch when only 1 scenario is true or evaluates down the list when when not true if you don't break.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am afraid I don't understand your last post, NM.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Predicates? That was one of my ideas. It means you can do it all in one statement. You can also start by filtering with one filter and gradually add new filters. If each filter is like age, you might end up with 24 lines between stream() and the collect() call. Far better than my 256 different case XYZ:s.
 
Sheriff
Posts: 14990
250
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would combine Piet's suggestion with a Builder to encapsulate the logic for creating a layered Predicate to use for filtering on multiple criteria.
 
Junilu Lacar
Sheriff
Posts: 14990
250
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is, you'd want to be able to write something like this:
 
Bartender
Posts: 731
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One way without switch is to not include the same test condition when unnecessary:
 
Sheriff
Posts: 6801
182
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem is that there are eight predicates, so using if-else isn't going to be practical.
 
Les Morgan
Rancher
Posts: 858
20
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you are looking to qualify populations or sample records, you cannot use a "select case" statement in that the cases are distinct values; the real utility of the work is that you can build complex qualifications to choose from your universal set.

From what I was interpreting being done, is simple filtering, say choosing people that are over 6' tall with blue eyes and have a hitchhiker's thumb.  Those would be but three of the bits in the mask, there may be many more, but you could choose from the universe by using that pattern to process the mask.  I've done that, fairly successfully, as part of a few projects that have well-defined criteria to build sample sets.

so as I said before, you can have all predicates checked in one line where you build the mask, then apply it to each record mask--a simple bitwise and will do, and exclusive or's if you need exclusions of this and only this.
 
Piet Souris
Bartender
Posts: 3747
154
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I like Junilu's suggestion of using a Builder. Here's an implementation:
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I presume the filters are associative, so it doesn't matter which order the criteria are evaluated in.
 
Piet Souris
Bartender
Posts: 3747
154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A genuine course would say: prove or disprove.
 
Junilu Lacar
Sheriff
Posts: 14990
250
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you have predicates p1, p2, p3, then p1.and(p2).and(p3) is equivalent to p1 && p2 && p3 in order of evaluation and in the shortcutting.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:. . . prove or disprove.

a ∧ b ⇒ b ∧ a
┏━━━━━━━
┃ 1  a ∧ b          ASSUMPTION
     ┏━━━━━
     ┃  2      a        AND (1)
     ┃  3      b        AND (1)
     ┗━━━━━
┃  4  b ∧ a         CONJ (2, 3)
┗━━━━━━━
5  a ∧ b ⇒ b ∧ a        DED (4) QED
 
Junilu Lacar
Sheriff
Posts: 14990
250
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:a ∧ b ⇒ b ∧ a
...
a ∧ b ⇒ b ∧ a        DED (4) QED



This is the commutative property though, not associative. Associative is a && (b && c) == (a && b) && c
 
Piet Souris
Bartender
Posts: 3747
154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was Thinking in terms of (F & T) & T =? F & (T & T), also operationally (the same number of Predicates are evauated both left and right, taking shortcutting into account.

Anyway, wonder what OP thinks of all this.
 
Campbell Ritchie
Marshal
Posts: 67939
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . the commutative property though, not associative. . . .

Yes, I had forgotten the proper names.
 
Greenhorn
Posts: 9
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Depending in which form you will represent the data it could be as simple as constructing the 'WHERE' part of the SQL query.
You just add one line for every filter IF this filter is 'true'.
But if you use plain Java structures then you have something like:

Then you may have a filter set class, like:

Then you'll have a list of PersonInfo records and a filter:

Then you can do:

This fully satisfies the original requirements and you only need one block of code for each filter condition.
 
Knute Snortum
Sheriff
Posts: 6801
182
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you UseCodeTags (that's a link), your code will be much clearer.  Please edit you post and add them.

[Edit: thank you]
 
eat bricks! HA! And here's another one! And a tiny ad!
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!