将索引数组的关联数组转换为多行csv文本


Convert associative array of indexed arrays into multi-line csv text

我有一个多维数组,其中第一级键需要是.csv字符串中的第一行数据。

索引元素的行需要转置并转换为csv文本的后续行。

输出将与。csv文件的内容相同,但我不想创建一个文件,只是作为一个。csv字符串。

样本数据:

$data = [
     'dates' => ['2010-01-02', '2011-02-03', '2011-02-04'],
     'type1' => ['data1', 'data2', 'data3'],
     'type2' => ['data4', 'data5', 'data6']
];

期望输出字符串:

dates,type1,type2
2010-01-02,data1,data4
2011-02-03,data2,data5
2011-02-04,data3,data6

像这样的东西可能会接近你想要的(没有测试,只是我的头):

$fh = fopen('file.csv', 'w');
// write out the headers
fputcsv($fh, array_keys($data));
// write out the data    
for ($i = 0; $i < count($data['dates']); $i++) {
    $temp = array($data['dates'][$i], $data['type1'][$i], $data['type2'][$i]);
    fputcsv($fh, $temp);
}

这比您可能需要的要冗长得多,但它允许您拥有一个包含n个元素的数组。zip基于同名的Python函数。这不是我写的

$data = ($data);
$r = (call_user_func_array('zip', $data));
$fin = "";
$fin .= implode(',',array_keys($data)).PHP_EOL;
foreach($r as $arr)
{
    $fin .= implode(',',$arr).PHP_EOL;
}
// $fin now holds all the data. Do something with it and you're finished!
function zip() {
    $args = func_get_args();
    $zipped = array();
    $n = count($args);
    for ($i=0; $i<$n; ++$i) {
        reset($args[$i]);
    }
    while ($n) {
        $tmp = array();
        for ($i=0; $i<$n; ++$i) {
            if (key($args[$i]) === null) {
                break 2;
            }
            $tmp[] = current($args[$i]);
            next($args[$i]);
        }
        $zipped[] = $tmp;
    }
    return $zipped;
}

(查看评论中的对话)。

为此我创建了一个小类:https://gist.github.com/981720

您可以包含它并生成csv,如下所示:

CSV::export($field_names, $data, '', TRUE)

这与Marc B建议的完全相同,但是您写道您不想为此创建文件。流包装器的救援(没有测试,只是我的头顶):

$fh = fopen('php://memory', 'rw'); # don't create a file, write to memory instead
// write out the headers
fputcsv($fh, array_keys($data));
// write out the data    
for ($i = 0; $i < count($data['dates']); $i++) {
    $temp = array($data['dates'][$i], $data['type1'][$i], $data['type2'][$i]);
    fputcsv($fh, $temp);
}
rewind($fh);
$string = stream_get_contents($fh);
fclose($fh);

任务是创建一个.csv-ready字符串。换句话说,标题数据的逗号分隔行,后面跟着n转置的列数据,以逗号分隔行连接。

要转置多维数组,调用array_map()并为其提供一个未打包(...)索引数组,然后在回调(...$col)中收集数据列并内爆。

所有数据合并成一个字符串数组后,用'nPHP_EOL内爆第一层。

代码(演示):

echo implode(
         "'n",
         array_merge(
             [implode(',', array_keys($data))],
             array_map(
                 fn(...$col) => implode(',', $col),
                 ...array_values($data)
             )
         )
     );
输出:

dates,type1,type2
2010-01-02,data1,data4
2011-02-03,data2,data5
2011-02-04,data3,data6

对于期望的结果,这是一个可靠的动态代码片段,并且没有硬编码任何键名。