【问题标题】:merge rows csv by id ruby按 id ruby​​ 合并行 csv
【发布时间】:2012-06-13 22:47:16
【问题描述】:

我有一个 .csv 文件,为简单起见,它包含两个字段:ID 和 cmets。 id 的行是重复的,其中每个评论字段已经满足从它生成的任何表中的 max char 并且需要另一行。我现在需要使用 Ruby 将关联 cmets 合并在一起,从而为每个唯一 ID 创建一行。

为了说明,我正在尝试使用 Ruby 来制作:

ID |评论
1 |片段 1
1 |片段 2
2 |片段 1
3 |片段 1
3 |片段 2
3 |片段 3

进入这个:

ID |评论
1 |片段 1 片段 2
2 |片段 1
3 |片段 1 片段 2 片段 3

我已经接近找到一种使用inject({}) 和hashmap 的方法,但仍在努力正确合并所有数据。与此同时,我的代码似乎变得过于复杂,包含多个哈希和数组,只是为了对选择性行进行合并。

实现这种类型的行合并的最佳/最简单的方法是什么?可以只用数组来完成吗?

不胜感激有关在 Ruby 中通常如何执行此操作的建议。

【问题讨论】:

    标签: ruby hashmap inject fastercsv


    【解决方案1】:

    保留标题并按 ID 使用分组:

    rows = CSV.read 'comment.csv', :headers => true
    rows.group_by{|row| row['ID']}.values.each do |group|
      puts [group.first['ID'], group.map{|r| r['COMMENT']} * ' '] * ' | '
    end
    

    您可以使用 0 和 1,但我认为使用标题字段名称更清晰。

    【讨论】:

    • 这款完美,简洁优雅。发现我不需要像我的示例中那样使用管道分隔符,因此将每一行保留为数组...谢谢
    【解决方案2】:

    使用以下 csv 文件,tmp.csv

    1,fragment 11
    1,fragment 21
    2,fragment 21
    2,fragment 22
    3,fragment 31
    3,fragment 32
    3,fragment 33
    

    试试这个(使用 irb 演示)

    irb> require 'csv'
      => true
    irb> h = Hash.new
     => {} 
    irb> CSV.foreach("tmp.csv") {|r| h[r[0]] = h.key?(r[0]) ? h[r[0]] + r[1] : r[1]}
     => nil 
    irb> h
     => {"1"=>"fragment 11fragment 21", "2"=>"fragment 21fragment 22", "3"=>"fragment 31fragment 32fragment 33"}
    

    【讨论】:

    • can't convert nil into String 是我得到的 - 但可能是一个快速修复我可以写一个检查,虽然第一个建议适合我的需要
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2018-07-21
    • 2015-04-11
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多