phparraysmultidimensional-arrayconcatenationgrouping

Group row data in a 2d array by the first 3 columns then concatenate the remaining columns in each group with commas


I want to merge a multidimensional array values if the values are the same under the 'u','v' and 'w' keys.

$myarray = array (
  '0' => 
    array (
      'u' => '30', 
      'v' => '16', 
      'w' => '22',        
      'x' => '30', 
      'y' => '16', 
      'z' => '22',  
),
  '1' => 
    array (
      'u' => '32', 
      'v' => '25', 
      'w' => '1',        
      'x' => '30', 
      'y' => '16', 
      'z' => '22',
),   
  '2' => 
    array (
      'u' => '30', 
      'v' => '16', 
      'w' => '22',        
      'x' => '54', 
      'y' => '96', 
      'z' => '2',
),   
  '3' => 
    array (
      'u' => '30', 
      'v' => '16', 
      'w' => '22',        
      'x' => '3', 
      'y' => '1', 
      'z' => '6',
)    
); 

I want the output to be as below:

//OUTPUT

array (
  '0' => 
    array (
      'u' => '30', 
      'v' => '16', 
      'w' => '22',        
      'x' => '30,54,3', 
      'y' => '16,96,1', 
      'z' => '22,2,6',  
),
  '1' => 
    array (
      'u' => '32', 
      'v' => '25', 
      'w' => '1',        
      'x' => '30', 
      'y' => '16', 
      'z' => '22',
)   
) 

This is what I have tried to do so far, which has not worked out for me.

<?php
$n = 0;            
$output = [];
foreach ($myarray as $row) {
    
    $prevkey = key(array_slice($output, -1,1,true));// get previous array key    
    
    if(array_key_exists('0', $output)){
        
        if($output[$prevkey]['u'] == $row['u'] && $output[$prevkey]['v'] == $row['v'] &&   $output[$prevkey]['w'] == $row['w'] ){
            echo "yes <br>";
           $output += $row;
        }
        
    }else{
      $output[] = $row;  
    }
    $n++;
}

var_dump($output); 
?>

Solution

  • You can use array_reduce:

    $grouped = array_reduce($myarray, function ($result, $item) {
        $key = '';
        foreach (['u', 'v', 'w'] as $prop) {
            $key .= $item[$prop] . '_';
        }
        if (array_key_exists($key, $result)) {
            foreach (['x', 'y', 'z'] as $prop) {
                $result[$key][$prop] .= ',' . $item[$prop];
            }
        } else {
            $result[$key] = $item;
        }
        return $result;
    }, []);
    
    $result = array_values($grouped);
    

    Working example