1

I have written the function below that takes an array and outputs all combinations of it.

$option = array("a","b","c");

function combinations($array, $number) {
    if ($number == 1) {
        foreach ($array as $k => $v1) {
            echo $v1 . "<br>";
        }
    } elseif ($number == 2) {
        foreach ($array as $k => $v1) {
            foreach ($array as $key => $v2) {
                echo $v1 . " - " . $v2 . "<br>";
            }

        }
    } elseif ($number == 3) {
        foreach ($array as $k => $v1) {
            foreach ($array as $key => $v2) {
                foreach ($array as $key => $v3) {
                    echo $v1 . " - " . $v2 . " - " . $v3 . "<br>";
                }
            }
        }
    }
}

combinations($option, 2);

the output is:

a - a
a - b
a - c
b - a
b - b
b - c
c - a
c - b
c - c

It accepts a number as argument and returns either 1, 2 or 3 slots for the combination. However I do not know ahead of time how many slots there will be for the combination. Most of the time it is is likely to be between 1 and 3 but I was hoping there is a way to rewrite this so that it can cope with any number of slots.

I am new to PHP so I'm sure there is something simple I'm missing. I would be very grateful if anyone can point me in the right direction.

Update:

I'm not sure how this is a duplicate of php string permutation. If I understand their question correctly they are looking to make a 4 slot combination. I could accomplish this with another elseif block in the function. I am looking for a way to make this work to any number of slots. My apologies if I have misunderstood.

Community
  • 1
  • 1
ianw
  • 43
  • 5

1 Answers1

0
$option = array("a", "b");

function combinations($option, $number) {
    $combo = array_fill(0, $number, 0);
    $num_option = count($option);

    while (true) {
        // output the combination
        $output = array_fill(0, $number, 0);
        for ($i = 0; $i < $number; ++$i) {
            $output[$i] = $option[$combo[$i]];
        }
        echo implode(" - ", array_reverse($output)) . "<br>";

        // compute next combination
        $incpos = 0;
        while ($combo[$incpos] == $num_option-1) {
            $combo[$incpos++] = 0;
            if ($incpos >= $number) {
                // we wrapped around - end
                return;
            }
        }
        ++$combo[$incpos];
    }
}

combinations($option, 5);

This code works by treating the current combination as a base-N number with $number digits, where N is the number of values in the $option array. In each iteration, the combination matching the number is written out, and then the number is incremented by one. The loop is terminated when the base-N number wraps around back to zero.

Result:

a - a - a - a - a
a - a - a - a - b
a - a - a - b - a
a - a - a - b - b
a - a - b - a - a
a - a - b - a - b
a - a - b - b - a
a - a - b - b - b
a - b - a - a - a
a - b - a - a - b
a - b - a - b - a
a - b - a - b - b
a - b - b - a - a
a - b - b - a - b
a - b - b - b - a
a - b - b - b - b
b - a - a - a - a
b - a - a - a - b
b - a - a - b - a
b - a - a - b - b
b - a - b - a - a
b - a - b - a - b
b - a - b - b - a
b - a - b - b - b
b - b - a - a - a
b - b - a - a - b
b - b - a - b - a
b - b - a - b - b
b - b - b - a - a
b - b - b - a - b
b - b - b - b - a
b - b - b - b - b
Krzysztof Kosiński
  • 3,737
  • 1
  • 15
  • 21