Search code examples
phparrayssiblingsarray-merge

Merge arrays with same values


I have an array on input with ids of graphic elements and I need to find groups of them. I was trying to use array_search and array_marge but without success.

I have array of siblings:

'siblings' => 
    array (size=6)
      0 => 
        array (size=2)
          0 => int 0
          1 => int 1
      1 => 
        array (size=2)
          0 => int 2
          1 => int 3
      2 => 
        array (size=2)
          0 => int 3
          1 => int 5
      3 => 
        array (size=2)
          0 => int 4
          1 => int 6
      4 => 
        array (size=2)
          0 => int 4
          1 => int 7
      5 => 
        array (size=2)
          0 => int 6
          1 => int 7

I need output like following:

'groups' => 
    array (size=6)
      0 => 
        array (size=2)
          0 => int 0
          1 => int 1
      1 => 
        array (size=2)
          0 => int 2
          1 => int 3
          2 => int 5
      2 => 
        array (size=2)
          0 => int 4
          1 => int 6
          2 => int 7

I can output this by following:

    $groups[] = array_unique(array_merge($siblings[0]));
    $groups[] = array_unique(array_merge($siblings[1],$siblings[2]));
    $groups[] = array_unique(array_merge($siblings[3],$siblings[4],$siblings[5]));

    var_dump($groups); // will output the previous output of groups

But I need function that will work on large scale.


Solution

  • It may not be so efficient but it works. The normal idea is loop through the array, check the intersection of the current with the remaining inner arrays. If there is some intersection, just merge them into the current, otherwise prepare the next arrays set (to loop and extract the next group):

    $a = array('siblings' =>  array(array(0,1),array(2,3),array(3,5),
                                    array(4,6),array(4,7),array(6,7)));
    $g[] = $a["siblings"][0];
    $round = array_slice($a["siblings"],1);
    $temp = array();
    $i = 0;
    
    while(count($round) > 0){
      $v = array_shift($round);
      if(count(array_intersect($g[$i],$v)) > 0) 
          $g[$i] = array_unique(array_merge($g[$i],$v));
      else $temp[] = $v;
      if(count($round) == 0 && count($temp) > 0) {
        $g[] = $temp[0]; 
        $i++;
        $round = array_slice($temp,1);
        $temp = array();
      }
    }
    $groups["groups"] = $g;
    var_dump($groups);
    

    Result:

    array(1) { 
       ["groups"]=> array(3) {
                    [0]=> array(2) { 
                           [0]=> int(0) 
                           [1]=> int(1) } 
                    [1]=> array(3) { 
                           [0]=> int(2) 
                           [1]=> int(3) 
                           [3]=> int(5) } 
                    [2]=> array(3) { 
                           [0]=> int(4) 
                           [1]=> int(6) 
                           [2]=> int(7) } } }