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

时间:2017-01-14 05:26:36

标签: ruby csv hash

我有一个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之间的每个哈希值。我在each哈希上使用collectdata尝试了大约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 =/==范围。

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

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

它不在我的工作电脑上,所以我不能用它做一个粘贴盒。

2 个答案:

答案 0 :(得分:0)

使用Enumerable#select

{{1}}

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

答案 1 :(得分:0)

我只会在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?与列号的对应关系(created_at中的row.fields[1]?)。