php - Find every possible permutation of array values

909

Situation: there are 5 questions with multiple possible answers. Four of the questions can have a single answer with one having one or more answers. Any of the questions could have no answer.

I want to work out each and every possible combination of these answers.

I think this isn't a duplicate of this as it deals with possible permutations of single characters or numbers.


I believe this example would generate something like 230,400 possible permutations

$questions = array(
    "q1" => array(
        "1a",
        "1b",
        "1c"
    ),
    "q2" => array(
        "2a",
        "2b",
        "2c",
        "2d"
    ),
    "q3" => array(
        "3a",
        "3b",
        "3c"
    ),
    "q4" => array( // this question can have any number of these answers selected, or none
        "4a",
        "4b",
        "4c",
        "4d",
        "4e",
        "4f"
    ),
    "q5" => array(
        "5a",
        "5b",
        "5c"
    )
);
512

Answer

Solution:

I hope I've got your question right and that this answer seems helpful to you...

Initial conditions

In addition to your example, let's introduce a second array with information about which question(s) may have multiple answers:

$multi_questions = array('q4');

This would tell our algorithm described in the following that question 4 may have any number of answers selected, while all over questions may only have a single or no answer at all.

Number of possible combinations of answers

The set of answers selected for a specific question is independent from any other question. For a question with a total number ofn possible answers and maximum of 1 selected answer, the number of possible selections for that question isn+1. If the question allows the selection of multiple answers, there are2^n possible combinations for that question (each answer has two options: chosen or not chosen).

In your example, this leads to a total number of4 * 5 * 4 * 2^6 * 4 = 20480 possible combinations of selected answers. This number can be computed like follows:

$combinations = 1;
foreach ($questions as $q => $answers)
{
    if (in_array($q, $multi_questions))
        $combinations *= 1 << count($answers);
    else
        $combinations *= count($answers) + 1;
}

Iterating over all possible combinations of answers

If you are not only interested in the number of answer combinations, but want to generate them all, you can use an algorithm like the following. For the questions with more than one possible answer, it encodes the set of answers given as binary number. That means, the number001010 would represent the answer set['4c','4e'].

$q_keys = array_keys($questions);

// Start with no answer selected for any question
$answer_set = array();
$q_max = array();
for ($i = 0; $i < count($q_keys); $i++)
{
    $answer_set[$i] = 0;
    $q_max[$i] = (in_array($q_keys[$i], $multi_questions))
                 ? (1 << count($questions[$q_keys[$i]])) - 1
                 : count($questions[$q_keys[$i]]);
}

// Iterate over all combinations of answers
while ($answer_set[0] <= $q_max[0])
{

    // Decode answer set to array of selected answers for each question
    $answers = array();
    for ($i = 0; $i < count($q_keys); $i++)
    {
        if (in_array($q_keys[$i], $multi_questions))
        {
            $answers[$q_keys[$i]] = array();
            for ($a = 0; $a < count($questions[$q_keys[$i]]); $a++)
                if (($answer_set[$i] & (1 << $a)) != 0) // Is the bit corresponding to answer no. $a set?
                    $answers[$q_keys[$i]][] = $questions[$q_keys[$i]][$a];
        }
        else
            $answers[$q_keys[$i]] = ($answer_set[$i] > 0)
                                    ? array($questions[$q_keys[$i]][$answer_set[$i] - 1])
                                    : array(); // Encode no answer as empty array
    }

    // Do something with the array of answers for each question ($answers)
    // ...

    // Forward the answer set
    for ($i = count($q_keys) - 1; $i >= 0; $i--)
    {
        if (++$answer_set[$i] > $q_max[$i] && $i > 0)
            $answer_set[$i] = 0;
        else
            break;
    }

}

People are also looking for solutions to the problem: php - unable to connect database : Codeigniter

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.