如何从CSV文件中解析散列哈希值

我有一个CSV文件,我需要读取并提取在一定范围内具有“created_at”的所有行 . CSV本身在Excel中约为5000行 .

这是我从文件中提取信息的方式:

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

这是使用 CSV.foreach 后创建的最后一个哈希:

2760=>{:created_at=>1483189568, :readable_date=>"12/31/2016", :first_name=>"Louise", :last_name=>"Garza", :email=>"lgarza24n@drupal.org", :gender=>"Female", :company=>"Cogilith", :currency=>"EUR", :word=>"orchestration", :drug_brand=>"EPIVIR", :drug_name=>"lamivudine", :drug_company=>"State of Florida DOH Central Pharmacy", :pill_color=>"Maroon", :frequency=>"Yearly", :token=>"_", :keywords=>"in faucibus", :bitcoin_address=>"19jTjXLPQUL1nEmHrpqeqM1FdtDFZmUZ2E"}}

当我运行 data[2759].first 时,我得到:

created_at
1309380645

我需要拉 created_at 介于 range = 1403321503..1406082945 之间的每个哈希 . 我在 data 哈希上使用 eachcollect 尝试了大约20种不同的方法但没有成功 . 我的最后一次尝试为每个原始哈希打印出一个空的 {} .

我试图测试这个没有成功:

data.each do |hash|
  if hash.first.to_s.to_i > 1403321503 && hash.first.to_s.to_i < 1406082945
    puts hash
  end
end

我不确定如何隔离 key:created_at 的值,然后查看它是否在范围内 . 我也试过做 hash.first.to_s.to_i =/== 范围 .

我可以通过使用 data[1].first.last 获得 :created_at 值,但是当我尝试在方法中使用它时会出错 .

以下是原始CSV的链接:goo.gl/NOjAPo

它不在我的工作计算机上,所以我不能做它的pastebin .

回答(2)

3 years ago

我只会在 data 哈希中存储范围内的行 . 执行更好的IMO,因为它需要的内存少于将所有数据读入 data 并在第二步中删除不需要的条目 .

DATE_RANGE = (1403321503..1406082945)

CSV.foreach("sample_data.csv", 
            :headers => true, 
            :header_converters => :symbol, 
            :converters => :all) do |row|
  attrs = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
  data[row.fields[0]] = attrs if DATE_RANGE.cover?(attrs[:created_at])
end

通过检查 DATE_RANGE.cover? 与列号(在 row.fields[1] 中是 created_at ?)来检查实际创建哈希之前的条件可能是有意义的 .

3 years ago

使用Enumerable#select

hash.select do |_, v|
  (1403321503..1406082945) === v[:created_at]
end

这里我们还使用Range#===(也称为case-equal或triple-equal)来检查值是否在范围内 .