ThinkTank ThinkTank - 3 months ago 10
PHP Question

PHP Find unique combinations with the good order

I'm working on a back office for a multiple-choice questionnaire.
For a question, you can have 2 types of answers : obligatory and optionnal.
The tricky part is about optionnal answers.

For exemple :
You have 4 optionnal answers "c||b||a||d".
First thing, I need to order them to limit the number of solution so I have : ""a||b||c||d" (this part is okay, just need to sort ;) )

Now, here are the solutions I need :

a
b
c
d
--------
a+b
a+c
a+d
b+c
b+d
c+d
--------
a+b+c
a+b+d
a+c+d
b+c+d
--------
a+b+c+d


For the moment, what I have tried :

$listIdOptionnal = array('a', 'b', 'c', 'd');

$tmpListMatrice = array();
//lette courante
for($i = 0; $i < sizeof($listIdOptionnal); $i++)
{
$tmpListMatrice[] = $listIdOptionnal[$i];

//position suivante
for($j = $i+1; $j < sizeof($listIdOptionnal); $j++)
{
//$tmpListMatrice[] = $listIdOptionnal[$i].','.$listIdOptionnal[$j];

//Longueur
for($k = 1; $k < sizeof($listIdOptionnal); $k++)
{
$tmp = array_slice($listIdOptionnal, $j, $k);
$tmpListMatrice[] = $listIdOptionnal[$i].','.implode(',', $tmp);
}
}
}

$tmpListMatrice = array_unique($tmpListMatrice);
var_dump($tmpListMatrice);exit;


My current result :

array(14) {
[0]=>
string(1) "a"
[1]=>
string(3) "a,b"
[2]=>
string(5) "a,b,c"
[3]=>
string(7) "a,b,c,d"
[4]=>
string(3) "a,c"
[5]=>
string(5) "a,c,d"
[7]=>
string(3) "a,d"
[10]=>
string(1) "b"
[11]=>
string(3) "b,c"
[12]=>
string(5) "b,c,d"
[14]=>
string(3) "b,d"
[17]=>
string(1) "c"
[18]=>
string(3) "c,d"
[21]=>
string(1) "d"
}


As you can see, my solution is not the good one because here is missing "a, b, d"

Answer

Try this :

$array = array('a', 'b', 'c', 'd');

$cnt  = count($array);
$return = array();

for($i = 1; $i < (1 << $cnt); $i++) {
    $str = '';
    for($j = 0; $j < $cnt; $j++)
        if($i & (1 << $j))
            $str .= $array[$j] . ',';
    $return[] = $str;
}

foreach ($return as $key=>$elmt)
    $return[$key] = substr($elmt, 0, -1);

var_dump($return);

Output :

array (size=15)
  0 => string 'a' (length=1)
  1 => string 'b' (length=1)
  2 => string 'a,b' (length=3)
  3 => string 'c' (length=1)
  4 => string 'a,c' (length=3)
  5 => string 'b,c' (length=3)
  6 => string 'a,b,c' (length=5)
  7 => string 'd' (length=1)
  8 => string 'a,d' (length=3)
  9 => string 'b,d' (length=3)
  10 => string 'a,b,d' (length=5)
  11 => string 'c,d' (length=3)
  12 => string 'a,c,d' (length=5)
  13 => string 'b,c,d' (length=5)
  14 => string 'a,b,c,d' (length=7)
Comments