如何使用Node-CSV倍增和跳过管道流行

zsbz8rwp  于 2022-12-12  发布在  Node.js
关注(0)|答案(2)|浏览(117)

我想使用Node CSV(https://csv.js.org/transform)将一个N行宽、多列的CSV输入流转换为一个(m · N)行窄、列少的CSV输出流。
输入和输出文件很大,所以我不能在实际限制内将其累积在内存中,但流管道应该可以工作。
但是我不知道如何调用CSV.transform。在下面的例子中,对于每个原始行,它返回一个m行的数组,但这失败了,因为CSV.stringify( )似乎试图将每个m行的数组解释为一个单行对象本身。
官方示例(https://csv.js.org/transform/examples/)和我能找到的其他示例(例如https://stackoverflow.com/a/25159167/645715)要么在内存中累积整个数组,要么每行返回一个row对象。

const CSV = require('csv')
        const inputStream = fs.createReadStream(INPUT_FILE)
        const outputStream = fs.createWriteStream(OUTPUT_FILE)
        inputStream
            .pipe(CSV.parse({columns: true}))
            .pipe(CSV.transform(function(row, callback) {
              var substack = []
              // turn 1 wide row into an array of m narrower rows 
              // for (i=1 ... m) substack.push({...})
              return callback( null, substack) // this doesn't work
             })        
            .pipe(CSV.stringify({header: true}))           
            .pipe(outputStream)
            .on('error', reject)
            .on('end', resolve)
vhmi4jdf

vhmi4jdf1#

我已经用了如下

const filterTransform = new Transform({
  objectMode: true,
  transform(chunk, encoding, callback) {
    const row = JSON.parse(chunk.toString());
    
    // Ignore a row based on condition
    if (row.id !== 'xxx') {
      this.push(row);
    }
    
    callback();
  },
});
qkf9rpyu

qkf9rpyu2#

啊哈,诀窍是为每个子行发出数据

.pipe(CSV.transform(function(row, callback) {
              count++
              for (var i=0; i<m; i++) {
                let new_row = {count, i, ...} // create new row
                this.emit('data',new_row) // emit new row
              }
              callback()
            }) , {})

相关问题