skip to Main Content

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']
]

So, as you can see, the result is a combination of array but they are all uniques. I mean these 2 array [‘A’, ‘B’] and [‘B’, ‘A’] is not wanted. And values in arrays need to be sorted in alphanumeric order.

Unless I’m wrong, an array with 4 values gives 10 possibles and uniques combinations.

Thanks for your help.

2

Answers


  1. <?php
        
        $payload = ['a', 'b', 'c', 'd'];
        
        function permutations($payload) {
            if (empty($payload)) { 
                return [[]];
            }
        
            $results = [];
            foreach ($payload as $key => $value) {
                foreach (permutations(array_diff_key($payload, [$key => $value])) as $subarray) {
                    $results[] = array_merge([$value], $subarray);
                }
            }
        
            return $results;
        }
        
        $permutations = array_map('implode', permutations($payload));
        print_r($permutations);
        
    ?>
    
    Login or Signup to reply.
  2. You need a power set of the given elements with the additional filters of removing individual elements and the entire set as a whole.

    So, for a collection of 4 elements, total 15 combinations are possible. For your case, we will have to remove 4 individual elements and the whole set itself making it 10 different sets or combinations.

    For every integer from 1 to 14, 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);
    

    Online Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search