按一列值对行数据进行分组,并用另一列值填充每组中的子数组


Group row data by one column value and populate a subarray in each group with the other column value

我想将数组中的数据与关联行进行分组。组应由type值确定,并且每个组内的所有label_id值应形成子阵列。

样本输入:

$array = [
    ['type' => 'AAA', 'label_id' => 'A1,35'],
    ['type' => 'AAA', 'label_id' => 'A2,34'],
    ['type' => 'BBB', 'label_id' => 'B1,29'],
    ['type' => 'CCC', 'label_id' => 'C1,20'],
    ['type' => 'CCC', 'label_id' => 'C2,19'],
    ['type' => 'CCC', 'label_id' => 'C3,18']
];

所需结果:

[
    [
        'type' => 'AAA',
        'label_id' => [
            'A1,35',
            'A2,34'
        ],
    [
        'type' => 'BBB',
        'label_id' => [
            'B1,29'
        ],
    ],
    [
        'type' => 'CCC',
        'label_id' => [
            'C1,20',
            'C2,19',
            'C3,18',
        ]
    ]
]

这应该可以完成

$args = array
(
    array( 'type' => 'AAA', 'label_id' => 'A1,35' ),
    array( 'type' => 'AAA', 'label_id' => 'A2,34' ),
    array( 'type' => 'BBB', 'label_id' => 'B1,29' ),
    array( 'type' => 'CCC', 'label_id' => 'C1,20' ),
    array( 'type' => 'CCC', 'label_id' => 'C2,19' ),
    array( 'type' => 'CCC', 'label_id' => 'C3,18' )  
);
$tmp = array();
foreach($args as $arg)
{
    $tmp[$arg['type']][] = $arg['label_id'];
}
$output = array();
foreach($tmp as $type => $labels)
{
    $output[] = array(
        'type' => $type,
        'label_id' => $labels
    );
}
var_dump($output);

输出为:

array
  0 => 
    array
      'type' => string 'AAA' (length=3)
      'label_id' => 
        array
          0 => string 'A1,35' (length=5)
          1 => string 'A2,34' (length=5)
  1 => 
    array
      'type' => string 'BBB' (length=3)
      'label_id' => 
        array
          0 => string 'B1,29' (length=5)
  2 => 
    array
      'type' => string 'CCC' (length=3)
      'label_id' => 
        array
          0 => string 'C1,20' (length=5)
          1 => string 'C2,19' (length=5)
          2 => string 'C3,18' (length=5)
<?php
$grouped_types = array();
foreach($types as $type){
        $grouped_types[$type['type']][] = $type;
}
?>

这个任务可以而且应该用一个循环来完成。

在存储相应的行数据时,使用type值作为临时分组关键字。空合并赋值运算符(??=)不是必需的(它可能是=,每次都覆盖相同的值),但它会努力防止在缓存值上重写相同的值。

label_id值推送到每个相应组的子阵列中。循环结束后重新索引数组。

代码:(演示)

$result = [];
foreach ($array as $row) {
    $result[$row['type']]['type'] ??= $row['type'];
    $result[$row['type']]['label_id'][] = $row['label_id'];
}
var_export(array_values($result));

对于函数式编码样式,请使用与上一个代码段具有相同正文的array_reduce()。当结果中的元素的数量可能与输入阵列中的元素数量不同时,CCD_ 8是合适的。(演示)

var_export(
    array_values(
        array_reduce(
            $array,
            function($result, $row) {
                $result[$row['type']]['type'] ??= $row['type'];
                $result[$row['type']]['label_id'][] = $row['label_id'];
                return $result;
            },
            []
        )
    )
);

如果你想用它变得时髦(不专业),你可以写一个具有相同功能/输出的无正文循环。(演示)

$result = [];
foreach ($array as [
    'type' => $type,
    'label_id' => $id,
    'type' => $result[$type]['type'], 
    'label_id' => $result[$type]['label_id'][]
]);
var_export(array_values($result));
$args = array(
    array('type' => 'AAA', 'label_id' => 'A1,35'),
    array('type' => 'AAA', 'label_id' => 'A2,34'),
    array('type' => 'BBB', 'label_id' => 'B1,29'),
    array('type' => 'CCC', 'label_id' => 'C1,20'),
    array('type' => 'CCC', 'label_id' => 'C2,19'),
    array('type' => 'CCC', 'label_id' => 'C3,18')
);
$result = [];
foreach ($args as $row) {
    $compositeKey = $row['type'];
    $result[$compositeKey] = [
        'type' => $row['type'],
        'label_id' => array_merge($result[$compositeKey]['label_id'] ?? [], [
            $row['label_id']
        ])
    ];
}
print_r(array_values($result));

输出:

array (
  0 =>
  array (
    'type' => 'AAA',
    'label_id' =>
    array (
      0 => 'A1,35',
      1 => 'A2,34',
    ),
  ),
  1 =>
  array (
    'type' => 'BBB',
    'label_id' =>
    array (
      0 => 'B1,29',
    ),
  ),
  2 =>
  array (
    'type' => 'CCC',
    'label_id' =>
    array (
      0 => 'C1,20',
      1 => 'C2,19',
      2 => 'C3,18',
    ),
  ),
)