Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimising treelike control structure

I have to create reports based on the user input. User answer a question, and then depending on the answer I go left or right in a treelike structure, and ask a new question. Some nodes will have the same question, but different children. I am not sure what would be the best way to do it in terms of code readability?

I would like to avoid huge control structure, as it would be extremely unreadable, like this:

if() {
    if() {
        if() {
            if() {
                ... 
            }
        }
        else {
            if() {
                ...
            }
        }
    }
    else {
        ...
    }
}
else {
    if() {
        if() {
            if() {
                ...
            }
        }
        else {
            if () {
                ...
            }
        }
    }
}

Is there some better way to deal with it? Here is an image of how my tree looks like

enter image description here

like image 725
Marko D Avatar asked Mar 14 '13 09:03

Marko D


2 Answers

Store the tree as data and then your code can be really quite small. If we modify the answer given by @jam6549 a little we can come up with something like this:

var answer = [ {t: "Does it have fur?", y: 1,  n: 2},
               {t: "Is it a kitten?",   y: 3,  n: 4},
               {t: "Is it a goldfish?", y: 5,  n: 4},
               {t: "Found a kitten",    y: -1, n: -1},
               {t: "I'm stumped",       y: -1, n: -1},
               {t: "Found a goldfish",  y: -1, n: -1} ];
var state = 0;

while ( answer[state].y >= 0 ) {
    var choice = confirm(answer[state].t);
    state = choice? answer[state].y: answer[state].n;
}
alert(answer[state].t);

This only supports simple y/n answers so I could use confirm, you'll want to use an array with an entry for each possible answer.

You say some of the questions are repeated so I'd be tempted to have an array with each unique question text. Then your answer array stores an index into the question array to save duplicating text.

like image 76
SpacedMonkey Avatar answered Oct 04 '22 03:10

SpacedMonkey


If you are using mysql then simply have a table for questions and a table for answers like so:

Question Table:

+----------+-----------+
| id       | question  |
+----------+-----------+
| 1        | Question 1|
+----------+-----------+
| 2        | Question 2|
+----------+-----------+
| 3        | Question 3|
+----------+-----------+

Answers Table:

+----------+-----------+-----------+---------------+
| id       | answer    | question  | next_question |
+----------+-----------+-----------+---------------+
| 1        | Answer 1  | 1         | 2             |
+----------+-----------+-----------+---------------+ 
| 2        | Answer 2  | 1         | 3             | 
+----------+-----------+-----------+---------------+

If the user is on question 1 and selects the first answer, they go to question 2. If they select the second answer they go to question 3.

So in your code just query the database after every answer using the id:

SELECT next_question FROM answers WHERE id = ?; // Change '?' depending on answer to get next question

Then get the next answers like so:

SELECT answer FROM answers WHERE question = ?; // Change '?' depending on previous value retrieved

Hope that helps.

like image 30
JWMarchant Avatar answered Oct 04 '22 02:10

JWMarchant