首页 > 解决方案 > 将 CSV 流与节点合并,尝试发出标头一次且仅一次

问题描述

使用 Node.js 和NodeCSV

我正在循环多个 CSV 流,并尝试将它们合并为一个 CSV,并将标题行作为第一行。我也在过滤以仅获取time列晚于给定时间的记录,尽管我很确定这部分与我的问题无关。

输入 CSV 具有标题行,其中一些可能不包含预期的列,在这种情况下,它们应该通过而不发出任何记录。

代码(为简洁而修改,请原谅复制/粘贴/复制错误)是这样的:

const csv = require('csv');
let header = true; // first record should emit a header line
const streams = [_array, _of, _read, _streams];
const lastIndex = streams.length - 1;
const sinceTime = Date.parse(someTime);
for (const [i, s] of streams.entries()) {
    s
        .pipe(csv.parse({columns: true}))
        .pipe(csv.transform(function (record) {
            const recordTime = Date.parse(record.time);
            if (recordTime > sinceTime) {
                return record;
            }
        }))
        .pipe(csv.stringify({
            columns: ['time', 'col'],
            header: header
        }))
        .pipe(output, {end: i === lastIndex});

    // this should only be cleared if the file actually emitted a header, but how do I know!?
    header = false;
}

当第一个输入文件不包含timeandcol列时,就会出现问题,假设它是一个带有XandY列的 csv。

在这种情况下,文件不会发出任何记录(如所希望的那样),但结果它也不会发出标题行。但我不知道,并愉快地将header布尔值设置为false. 然后我的输出不包含标题行,这不是我想要的。

如果第一个文件包含预期的列timeand col,那么一切都很好,我从第一个文件中获取标题行。

即使第一个文件没有发出任何记录,我该如何处理这种情况并发出标题行?

更新:

我想到了以下解决方案,它有效,但似乎必须有更好的方法。我尝试在循环之前生成一个带有标题的空 CSV,如下所示:

const csv = require('csv');
const streams = [_array, _of, _read, _streams];
const lastIndex = streams.length - 1;
const sinceTime = Date.parse(someTime);
const columns = ['time', 'col'];

// generate the header line with an empty CSV
csv
    .generate({length: 0})
    .pipe(csv.parse({columns: true}))
    .pipe(csv.stringify({
        columns: columns,
        header: true
    }))
    .pipe(output, {end: false});

for (const [i, s] of streams.entries()) {
    s
        .pipe(csv.parse({columns: true}))
        .pipe(csv.transform(function (record) {
            const recordTime = Date.parse(record.time);
            if (recordTime > sinceTime) {
                return record;
            }
        }))
        .pipe(csv.stringify({
            columns: columns,
            header: false
        }))
        .pipe(output, {end: i === lastIndex});
}

丑陋,但它正在做我想做的事。有没有更清洁的方法?

标签: node.jscsv

解决方案


推荐阅读