1

Related to Generating all the combinations of a set of boolean variables in Haskell and various other questions of the type.

I have a bunch of toggle switches in a database and want to get a list of all possible settings. The number of switches can change, specifically, users can add or remove.

I can get them into an array like

$switches = array('aaa', 'bbb', 'ccc');

and I would like to generate all possibilities, i.e. something like:

$states = array(
array('aaa' => false, 'bbb' => false, 'ccc' => false),
array('aaa' => false, 'bbb' => false, 'ccc' => true),
array('aaa' => false, 'bbb' => true, 'ccc' => false),
array('aaa' => false, 'bbb' => true, 'ccc' => true),
...
);

I don't particularily care in which order the result set is.

What's an elegant way to generate that?

Tom
  • 2,688
  • 3
  • 29
  • 53

2 Answers2

1

Dunno if it's elegant, but for example use array_reduce with a callback:

$a = ['a', 'b', 'c'];
$states = array_reduce($a, function ($t, $v) {
    $newt = [];
    if (empty($t)) {
        $newt = [
            [$v => false],
            [$v => true],
        ];
    } else {
        foreach ($t as $item) {
            $newt[] = array_merge($item, [$v => false]);
            $newt[] = array_merge($item, [$v => true]);
        }
    }

    return $newt;
}, []);
var_dump($states);
u_mulder
  • 54,101
  • 5
  • 48
  • 64
  • replace the array_merge with the + operator and it works for numerical keys, too. – Tom Mar 06 '19 at 09:47
0

I would have going or the idea of using the binary representation of integers (using decbin):

$keys = ["aaa", "bbb", "ccc"];
$n = count($keys);
for($i = 0; $i < pow(2,$n); $i++) {
    $num = array_reverse(str_split(decbin($i)));
    $res[] = array_pad($num, $n, 0);   
}

foreach($res as &$e) // adding the keys to the result
    $e = array_combine($keys, $e);

Notice the decbin can return string less then 2^$n so I reverse the string and pad with 0 using array-pad

Notice this will generate array with 0 and 1 instead of true and false but in PHP they very much alike - anyway, swapping them for true and false is easy enough so I leave it to you...

dWinder
  • 11,597
  • 3
  • 24
  • 39