PHP Permutations with exception of similar sequence

My permutation/combinations of data

$combinations = [[]];
$data = [

        ['alteration1', 'alteration2', 'alteration3', 'alteration4' ... upto 5 each],
        ['alteration1', 'alteration5', 'alteration6', 'alteration7' ... upto 5 each],
        ['alteration8', 'alteration9', 'alteration10', 'alteration5' ... upto 5 each],
        ... upto 6 max
    ];

    $length = count($data);

    for ($count = 0; $count < $length; $count++) {
        $tmp = [];
        foreach ($combinations as $v1) {
            foreach ($data[$count] as $v2)
                $tmp[] = array_merge($v1, [$v2]);

        }
        $combinations = $tmp;
    }

  print_r($combinations);

The script would generate such sets

 0 => array:3 [▼
    0 => "alteration1"
    1 => "alteration1"
    2 => "alteration8"
  ]
  1 => array:3 [▼
    0 => "alteration1"
    1 => "alteration1"
    2 => "alteration9"
  ]

... the issue begins when I start getting the same sequences of data in my case array index 0 and 20 would be exactly the same despite any position.

 20 => array:3 [▼
        0 => "alteration8"
        1 => "alteration1"
        2 => "alteration1"
      ]
      21 => array:3 [▼
        0 => "alteration1"
        1 => "alteration9"
        2 => "alteration1"
      ]
 $final = []; // remove duplicates

The basic idea is to keep $combinations array's unique (alteration1,alteration2,alteration3) is equal to (alteration3,alteration1,alteration2) therfore it should be skipped in the $final array. I haven't really found anything around SO and google. Thanks for the help. $data dimentions [ from 1 - 6 ], each array inside can be [ 1 - 6 ]. Following script might not be working as expected .

http://sandbox.onlinephpfunctions.com/code/3ad5084386c2185f7619aaac152b638873039ee8

1 answer

  • answered 2019-11-07 14:01 vivek_23

    • We iterate over the data and find unique elements first for each set using array_unique.

    • We then natsort them to get a sorted form and serialize them using implode(). By doing this, we would get the same serialized code for sets ABC,CBA,BAC etc.

    • We then find duplicates using keys check inside a variable, say $set. If the serialized key is set, we exclude it from the results, else we include it in our final results.

    Snippet:

    <?php
    
    $data = [
        ['alteration1', 'alteration4',],
        ['alteration2','alteration3'],
        ['alteration2','alteration3'],
        []
    ];
    
    
    $combinations = [[]];
    
    foreach($data as $index => $current_data){
       $current_data = array_unique($current_data);   
       if(empty($current_data)) continue; 
       $temp_combinations = [];
       foreach($current_data as $value){
           foreach($combinations as $each_combination){
               $temp_combinations[] = array_merge($each_combination,[$value]);
           }
       }
    
       $combinations = $temp_combinations;
    
    }
    
    $set = [];
    $unique_combinations = [];
    
    foreach($combinations as $each_combination){
        natsort($each_combination);
        $serialized_form = implode(",",$each_combination);
        if(isset($set[$serialized_form])) continue;
        if(empty($each_combination)) continue;
        $unique_combinations[] = $each_combination;
        $set[$serialized_form] = true;
    }
    
    print_r($unique_combinations);
    

    Demo: https://3v4l.org/Do6oH