【问题标题】:Sum column in stream using node使用节点对流中的列求和
【发布时间】:2019-01-16 22:38:58
【问题描述】:

我的目标是计算与 csv 中另一列相关的列的总和。

例如,我有一个输入 csv,看起来像这样

"500","my.jpg"
"500","my.jpg"
"200","another.jpg"

我希望输出是:

[{ bytes: 1000, uri: "my.jpg" }, { bytes:200, "another.jpg" }]

注意:我需要以流的形式执行此操作,因为给定的 csv 可能有超过 300 万条记录,并且循环太慢了。

我已经设法使用awk 完成了这项工作,但我正在努力在节点中实现它

这是使用 awk 命令的 bash 脚本

awk -F, 'BEGIN { print "["}
{   
    gsub(/"/, ""); # Remove all quotation from csv
    uri=$2; # Put the current uri in key
    a[uri]++; # Increment the count of uris
    b[uri] = b[uri] + $1; # total up bytes
} 
END { 
    for (i in a) {
        printf "%s{\"uri\":\"%s\",\"count\":\"%s\",\"bytes\":\"%s\"}",
        separator, i, a[i], b[i]
        separator = ", "
    }

    print "]"
}
' ./res.csv

任何正确方向的指针将不胜感激

【问题讨论】:

    标签: node.js csv stream buffer


    【解决方案1】:

    您可以尝试为您的 csv 文件创建一个读取流并将其通过管道传输到 csv-streamify 解析器。

    const csv = require('csv-streamify')
    const fs = require('fs')
    
    const parser = csv()
    const sum = {};
    
    // emits each line as a buffer or as a string representing an array of fields
    parser.on('data', function (line) {
      let key = line[1];
      let val = line[0];
      if (!sum[key]) {
        sum[key] = 0;
      }
      sum[key] = sum[key] + parseInt(val);
      console.log("Current sum for " + key + ": " + sum[key])
    })
    
    parser.on('end', function () {
      let results = Object.keys(sum)
        .map(key => ({ bytes: sum[key], uri: key }))
      console.log(results);
    })
    
    // now pipe some data into it
    fs.createReadStream('./test.csv').pipe(parser)
    

    使用您的示例数据,此示例应打印:

    [ { bytes: 1000, uri: 'my.jpg' },
      { bytes: 200, uri: 'another.jpg' } ]
    

    【讨论】:

      【解决方案2】:

      您也可以尝试下面的 Perl 解决方案。

      $ cat url.txt
      "500","my.jpg"
      "500","my.jpg"
      "200","another.jpg"
      "600","more.jpg"
      
      $ perl -lne ' if(/\"(\d+)\",\"(.+?)\"/g) { $kv{$2}+=$1} ; END { print "["; for(keys %kv) { print "$s { bytes:$kv{$_} uri:\"$_\" } ";$s="," } print "]" } ' url.txt
      [
       { bytes:600 uri:"more.jpg" }
      , { bytes:200 uri:"another.jpg" }
      , { bytes:1000 uri:"my.jpg" }
      ]
      
      $
      

      【讨论】:

      • 这个方案比awk和node都快。谢谢你的替代品
      • @test.. 很高兴听到这个消息.. 请考虑为答案投票。
      • 我愿意,但我需要至少 15 个声望点才能投票:/
      猜你喜欢
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 2019-08-14
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      相关资源
      最近更新 更多