Ruby CSV:列的比较(来自两个csv),在一个

时间:2015-10-16 17:38:39

标签: ruby csv cross-reference

我已经搜索过,并没有找到针对这个特殊难题的方法。我有两个CSV文件,有时与同一件事有关。这是一个例子:

CSV1(500行):

date,reference,amount,type
10/13/2015,,1510.40,sale
10/13/2015,,312.90,sale
10/14/2015,,928.50,sale
10/15/2015,,820.25,sale
10/12/2015,,702.70,credit

CSV2(20000行):

reference,date,amount
243534985,10/13/2015,312.90
345893745,10/15/2015,820.25
086234523,10/14/2015,928.50
458235832,10/13/2015,1510.40

我的目标是将CSV2中的日期和金额与CSV1中的日期和金额相匹配,并将参考从CSV2写入相应行中的参考列。

这是一个简化的视图,因为CSV2实际上包含了很多列 - 这些只是相关的列,所以理想情况下我想通过标题名称引用它们或者以某种方式索引?

这是我尝试过的,但我有点卡住了。

require 'csv'

data1 = {}
data2 = {}

CSV.foreach("data1.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
  data1[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end

CSV.foreach("data2.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
  data2[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end

data1.each do |data1_row|
    data2.each do |data2_row|
        if (data1_row['comparitive'] == data2_row['comparitive'])
            puts data1_row['identifier'] + data2_row['column_thats_important_and_wanted']
        end
    end
end

结果:

22:in `[]': no implicit conversion of String into Integer (TypeError)

我也试过了:

CSV.foreach('data2.csv') do |data2|
    CSV.foreach('data1.csv') do |data1|
        if (data1[3] == data2[4])
            data1[1] << data2[1]
            puts "Change made!"
        else
            puts "nothing changed."
        end
    end
end

然而这与if语句中的任何内容都不匹配,所以也许不是正确的方法?

2 个答案:

答案 0 :(得分:0)

headers方法应该可以帮助您匹配列 - 从那里解析并将修改后的数据写回文件。

答案 1 :(得分:0)

解决。

data1 = CSV.read('data1.csv')
data2 = CSV.read('data2.csv')

data2.each do |data2|
    data1.each do |data1|
        if (data1[5] == data2[4])
            data1[1] = data2[1]
            puts "Change made!"
            puts data1
        end
    end
end

File.open('referenced.csv','w'){ |f| f << data1.map(&:to_csv).join("")}