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

发布于 2024-11-18 21:44:17 字数 464 浏览 3 评论 0原文

我有一个多维数组,其中第一级键需要是 .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

I have a multidimensional array in which the first level keys needs to be the first line of data in .csv string.

The rows of indexed elements need to be transpose and converted into subsequent lines of csv text.

The output will be identical to a .csv file's contents, but I don't want a file to be created, just as a .csv string.

Sample data:

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

Desired output string:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一生独一 2024-11-25 21:44:17

像这样的东西可能会接近你想要的(未经测试,只是从我的脑海中浮现出来):

$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);
}

Something like this would probably come close to what you want (not tested, just going off the top of my head):

$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);
}
待天淡蓝洁白时 2024-11-25 21:44:17

这比您可能需要的要详细得多,但它允许您拥有一个包含 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;
}

(看看评论里的对话。这真的很相关。)

This is much more verbose than you'll likely ever need, but it allows you to have an array of n elements. zip is based off of the Python function of the same name. I did not write it.

$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;
}

(check out the conversation in the comments. It's really relevant.)

当爱已成负担 2024-11-25 21:44:17

我为此做了一个小课程: https://gist.github.com/981720

你可以包括它并生成 csv,如下所示:

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

I made a little class for doing this: https://gist.github.com/981720

You can include it and generate the csv like so:

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

霞映澄塘 2024-11-25 21:44:17

这与 Marc B 的建议相同,但是您写道您不想为此创建文件。 Stream Wrappers 来救援(未经测试,只是从我的脑海中浮现出来):

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

This is merely the same as Marc B suggested, however you wrote that you didn't wanted to create a file for this. Stream Wrappers to the rescue (not tested, just going off the top of my head):

$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);
风柔一江水 2024-11-25 21:44:17

任务是创建一个 .csv 就绪字符串。换句话说,逗号分隔的标题数据行,后跟作为逗号分隔行连接的 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

这是一个可靠的动态片段,可实现所需的结果,并且绝不会硬编码任何内容关键名称。

The task is to create a .csv-ready string. In other words, a comma-delimited line of header data, followed by n number of transposed column data joined as comma-delimited lines.

To transpose a multidimensional array, call array_map() and feed it an unpacked (...) indexed array then collect columns of data inside the callback (...$col) and implode.

After all data is merged into a single array of strings, implode the first level with \n or PHP_EOL.

Code: (Demo)

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

Output:

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

This is a reliable dynamic snippet for the desired result and at no point hard codes any key names.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文