php 将二维数组中的行数据按前3列分组,然后用逗号连接每组中的其余列

46scxncf  于 2023-04-10  发布在  PHP
关注(0)|答案(3)|浏览(82)

我想合并一个多维数组的值,如果值在'u','v'和'w'键下相同。

$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',
)    
);

我希望输出如下:

//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',
)   
)

这就是我到目前为止所做的,但对我来说并不奏效。

<?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); 
?>
w8ntj3qf

w8ntj3qf1#

可以使用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

1zmg4dgp

1zmg4dgp2#

你可以根据这3个值创建一些特定的数组,并使用其特定的索引。例如:

$myarray = [...];

$supp = [];
foreach ($myarray as $ind => $arr){

    // remember 3 values and use them as a new index
    $uvw = sprintf('%d|%d|%d', $arr['u'], $arr['v'], $arr['w']); 

    if (!isset($supp[$uvw])){
        $supp[$uvw] = ['ind' => $ind, 'data' => $arr];
    } else {
         
        foreach($arr as $in => $new_val){ 
            foreach($supp[$uvw]['data'] as $i => &$val){
                if ($i === $in && !in_array($i,['u','v','w'])){
                    $val .= ',' . $new_val;
                }
            }
        }
    }
}

// recombine the output data (it also includes the parent index value)
$output = [];
foreach($supp as $arr_data){
    $output[$arr_data['ind']] = $arr_data['data'];
}

print_r($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
        )

)

Demo

6rvt4ljy

6rvt4ljy3#

如果将引用变量推入结果数组,则可以在单个循环中完成按多个列的分组,而无需在结束时重新索引。
vsprintf()是一种简单的方法,可以从每行的前3个值中创建一个分隔字符串-如果您需要显式命名标识键,因为它们不可靠地位于行的第一位,那么您可以手动访问它们以构建复合键。
只有在多次遇到组时才执行串联。
代码:(Demo

$result = [];
foreach ($array as $row) {
    $key = vsprintf('%d_%d_%d', $row);
    if (!isset($ref[$key])){
        $ref[$key] = $row;
        $result[] = &$ref[$key];
    } else {
        $ref[$key]['x'] .= ',' . $row['x'];
        $ref[$key]['y'] .= ',' . $row['y'];
        $ref[$key]['z'] .= ',' . $row['z'];
    }
}
var_export($result);

相关问题