csv 按一列对子数组进行分组,使组内其他列的值以逗号分隔

ou6hu8tu  于 2023-01-18  发布在  其他
关注(0)|答案(2)|浏览(107)

我有一个数组,看起来像这样:

$array = [
    ["444", "0081"],
    ["449", "0081"],
    ["451", "0081"],
    ["455", "2100"],
    ["469", "2100"]
];

我需要分组为一个新数组,如下所示:

array (
  0 => 
  array (
    0 => '444,449,451',
    1 => '0081',
  ),
  1 => 
  array (
    0 => '455,469',
    1 => '2100',
  ),
)

我试过很多剧本,但都不成功。

function _group_by($array, $key) {
    $return = array();
    foreach($array as $val) {
        $return[$val[$key]][] = $val;
    }
    return $return;
}
$newArray = _group_by($array, 1); // (NO SUCCESS)
r6vfmomb

r6vfmomb1#

应该有更优雅的解决方案,但我能想到的最简单的一个是这个。

// The data you have pasted in the question
$data = []; 
$groups = [];

// Go through the entire array $data
foreach($data as $item){
    // If the key doesn't exist in the new array yet, add it       
    if(!array_key_exists($item[1], $groups)){
        $groups[$item[1]] = [];
    }

    // Add the value to the array
    $groups[$item[1]][] = $item[0];
}

// Create an array for the data with the structure you requested
$structured = [];
foreach($groups as $group => $values){
    // With the array built in the last loop, implode it with a comma
    // Also add the 'key' from the last array to it ($group)
    $structured[] = [implode(',', $values), $group];
}

我还没有测试过这个,但是类似的东西应该可以完成这个任务。它只是遍历给定的数组,并以结构化的方式收集所有条目(因此$groups变量将包含每个共享键的组的数组条目,并且键将对应于给定数组中每个条目中的第二个条目)。从那里开始,它只需要重新构造它,以获得您所请求的格式。
http://php.net/manual/en/control-structures.foreach.php

cfh9epnr

cfh9epnr2#

编写两个循环对于此任务来说太费力了。请使用isset(),并在迭代时将临时键应用于输出数组。完成数据分组后,使用array_values()重新索引输出。
代码(Demo

$array = [
    ["444", "0081"],
    ["449", "0081"],
    ["451", "0081"],
    ["455", "2100"],
    ["469", "2100"]
];

foreach ($array as $row) {
    if (!isset($result[$row[1]])) {
        $result[$row[1]] = $row;  // first occurrence of group, save whole row
    } else {
        $result[$row[1]][0] .= ',' . $row[0];  // not first occurrence, concat first element in group
    }
}
var_export(array_values($result));

或者通过使用引用数组来避免结果数组中的临时关联数组。(Demo

$result = [];
foreach ($array as $row) {
    if (!isset($ref[$row[1]])) {
        $ref[$row[1]] = $row;
        $result[] = &$ref[$row[1]];
    } else {
        $ref[$row[1]][0] .= ',' . $row[0];
    }
}
var_export($result);

或者使用array_reduce()来享受函数式技术。(Demo

var_export(
    array_values(
        array_reduce(
            $array,
            function($result, $row) {
                if (!isset($result[$row[1]])) {
                    $result[$row[1]] = $row;
                } else {
                    $result[$row[1]][0] .= ',' . $row[0];
                }            
                return $result;
            }
        )
    )
);

全部将输出:

array (
  0 => 
  array (
    0 => '444,449,451',
    1 => '0081',
  ),
  1 => 
  array (
    0 => '455,469',
    1 => '2100',
  ),
)

相关问题