I have an array. This an example:
$array = ['A', 'B', 'C', 'D']
I would like all possible combination to get the following result:
$new_array = [
['A', 'B'], ['A', 'C'], ['A', 'D'],
['A', 'B', 'C'], ['A', 'B', 'D'], ['A', 'C', 'D'],
['B', 'C'], ['B', 'D'],
['B', 'C', 'D']
['C', 'D']
['A', 'B', 'C', 'D']
]
So, as you can see, the result is a combination of array but they are all uniques. I mean ['A', 'B'] shoud be in the outpout but not ['B', 'A']. Also values in arrays should be sorted in alphanumeric order.
Unless I'm wrong, an array with 4 values gives 11 possibles and uniques combinations.
Thanks for your help.
You need a power set of the given elements with the additional filters of removing individual elements.
So, for a collection of 4
elements, total 15
combinations are possible. For your case, we will have to remove 4
individual elements making it 11
different sets or combinations.
For every integer from 1
to 15
, we keep including all the elements whose index comes in the binary representation of the current integer in iteration and add them to the result. If any integer has only 1 bit set(meaning being a power of 2), it means it is an individual element and we simply continue
our loop skipping the processing part.
Finally, we use usort
to sort the sets alphabetically and use strcmp
to compare 2 different sets by converting them to strings using implode
separated by |
character to avoid any overlapping issues.
Snippet:
<?php
$payload = ['A', 'B', 'C', 'D'];
$total = (1 << count($payload)) - 1;
$result = [];
for($i = 1; $i <= $total; ++$i){
if(($i & ($i - 1)) == 0) continue; // avoiding single items since you don't wish to have them
$curr = [];
for($j = 0; $j < count($payload); ++$j){
if(($i & (1 << $j)) > 0){
$curr[] = $payload[ $j ];
}
}
$result[] = $curr;
}
usort($result, function($a, $b){
return strcmp( implode("|", $a), implode("|", $b) );
});
print_r($result);