function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Morpheus.ax1491Morpheus.ax1491 

Get Total Permutations of child objects in a list of lists.

Let's say I have a list of questions that stores an object that has a list of it's possible answers, and I need to generate all permutation pairs with no duplicates where one element of the pair is in the first list and the second one in the second list. In other words, let's say I have 2 questions, and each one has 2 answers, how many answer sets could I create with this? One last thing, the order is important. An answer from the first question could not be in the position from the 2nd question, if that makes sense.

 

I hope this is clear.

 

Thanks!

 

-- I also posted this up to the Salesforce StackExchange

Morpheus.ax1491Morpheus.ax1491
It's not so much an issue of governor limits as I have the formula to determine the total number of combinations, and if that number would exceed say 200, I won't be allowing the process to continue. That being said, what I'm having a harder time with is actually determining the logic to generate the list.

Thanks!
netspidernetspider

 

Can you provide the code you have written so far?

netspidernetspider

Are you saying that an ans can be for more than 1 ques and what determines if the ans should be linked to a ques or not.

 

In your example do you mean that the 2 ans will be linked to each of the 2 ques, so there are 4 possibilities in your example?

Morpheus.ax1491Morpheus.ax1491

In my example, there would be 4 possibilities that is correct. Perhaps some more information is necessary.

 

We have an Object called "Question__c". We have another object, "Answer__c". Answer__c has a lookup to Question__c.

 

In the Question__c object, we have a joiner object that can related a question to another question, so that the "child" question contributes to the answer on the "parent".

 

We also have one more object that we'll call ContributingQuestionCombos__c. Each record stores one possible combination.

 

Now, taking the Answers from the contributing questions, and the answers from the parent question, I am trying to make a CSV template that has all of the possible answer combinations for the options provided. There can be up to 4 "contributing" questions. Should the number of possible combinations be above 200, then I do not include the combinations in the CSV template. The columns in the CSV template are  ControllingQuestionId__c, Answer1__c, Answer2__c, Answer3__c, Answer4__c. 

 

Let's say we have 4 contributing questions, the answers from Question 1 can only ever be in the Answer1__c column, Question 2 can only be in Answer2__c, etc and so forth. 

 

Given that logic, what I'm trying to do is prepopulate this CSV Template with the combinations for the user and provided there aren't too many. 

 

So to answer your question directly, there would actually be 9 combinations total for 2 questions with 2 answers each as we are including blank answers as a potential combination. 

 

Question1 Question2

    A                      1

    B                      2

    A                      2

    B                      1

     -                       1

     -                       2

    A                       -

    B                       -

     -                        -

 

I hope that clarifies things a bit!

 

Thanks for taking the time to help, I really appreciate it :)

 

 

 

 

 

 

netspidernetspider

Question__c[] q = [Select id, que (Select id, ans From Answer__r) From Question__c];

String output = 'Ques,Ans1,Ans2,Ans3,Ans4\n';

 

for (Question__c eachq: q){

output += eachq.que;

for (Answer__c eachans: eachq.Answer__r)

output += ',' + eachans.ans;

}

 

I know this is no way complete but its a start, you will have to build this into a recursive function that will call back on itself until all ques and answers have been found.

Maybe if you write a bit of the functionality, pass it to me when you get stuck then I will write a bit more to fix whatever you are stuck on etc.

 

netspidernetspider

Slight change, this will only get all ans of 1 ques

 

for (Question__c eachq: q){

output += eachq.que;

for (Answer__c eachans: eachq.Answer__r)

output += ',' + eachans.ans;

 

output += '\n';

}

 

You might be better as well building Maps

Map<Que Id, Map<Ans Id, Map<Que Id, Map<Ans Id, Que id>>>>

Morpheus.ax1491Morpheus.ax1491

Here is the code I ended up with after getting some serious help from SE. 

 

public static List<Permutation> createPermutations(list<list<String>> questions) {

    List<Permutation> mutantList = new List<Permutation>();


    // add default values to the permutation field.    
    List<String> field1Values = 'blank'.split(',');
    List<String> field2Values = 'blank'.split(',');
    List<String> field3Values = 'blank'.split(',');
    List<String> field4Values = 'blank'.split(',');

    if(questions.size() > 0)
        field1Values.addAll(questions.get(0));
    if(questions.size() > 1)
        field2Values.addAll(questions.get(1));
    if(questions.size() > 2)
        field3Values.addAll(questions.get(2));
    if(questions.size() > 3)
        field4Values.addAll(questions.get(3)); 

    // calculate the permutations
    Integer aSize, bSize, cSize, dSize = 0;
    aSize = field1Values.size();
    bSize = field2Values.size();
    cSize = field3Values.size();
    dSize = field4Values.size();

    // number of records which need to be created is the number of permutations possible
    Integer totalPermutations = aSize * bSize * cSize * dSize;

    // make sure we didn't multiply anything by zero
    system.assertNotEquals(0, totalPermutations);

    // create one instance in the list for every permutation of data
    for (Integer a = 0; a < aSize; a++) {
        for (Integer b = 0; b < bSize; b++) {
            if(questions.size() > 2){
                for (Integer c = 0; c < cSize; c++) {
                    if(questions.size() > 3){
                        for (Integer d = 0; d < dSize; d++) {
                                // create the permutation instance
                                Permutation perm = new Permutation();
                                // set the data points
                                perm.field1 = field1Values[a];
                                perm.field2 = field2Values[b];
                                perm.field3 = field3Values[c];
                                perm.field4 = field4Values[d];

                                // add to the list of permutations being returned to the caller
                                mutantList.add(perm);
                        }
                    }else{
                        Permutation perm = new Permutation();

                        perm.field1 = field1Values[a];
                        perm.field2 = field2Values[b];
                        perm.field3 = field3Values[c];      

                        mutantList.add(perm);

                    }
                }                    
            }else{
                Permutation perm = new Permutation();

                perm.field1 = field1Values[a];
                perm.field2 = field2Values[b];

                mutantList.add(perm);
            }

        }                
    }


    return mutantList;
}

 

It's not perfect, and it is a massive resource hog, but for our application which will allow no more than 200 permutations at a time, it does the job well enough. It's currently under peer review, so it's not a final version, but I will be sure to post that up as well.

 

Thanks for the help! :)