将CSV文件转换为哈希数组

时间:2013-01-07 16:17:07

标签: ruby csv multidimensional-array

我有一个csv文件,一些曲棍球统计数据,例如:

09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5

我想将它们保存在一个哈希数组中。我没有任何标题,我想为每个值添加键,如"time" => "09.09.2008",依此类推。每行应该像arr[i]一样可访问,每个值例如arr[i]["time"]。我更喜欢CSV类,而不是FasterCSVsplit。你可以显示方式或重定向到某个解决类似问题的线程吗?

6 个答案:

答案 0 :(得分:69)

只需传递headers: true

CSV.foreach(data_file, headers: true) do |row|
  puts row.inspect # hash
end

从那里,您可以随心所欲地操纵哈希。

(使用Ruby 2.0测试过,但我认为这已经有一段时间了。)

修改

您说您没有任何标题 - 您可以在阅读文件内容的开头添加标题行吗?

答案 1 :(得分:34)

您可以使用Ruby CSV parser对其进行解析,然后使用Hash[ keys.zip(values) ]将其设为哈希值。

示例:

test = '''
09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5
'''.strip

keys = ['time', etc... ]
CSV.parse(test).map {|a| Hash[ keys.zip(a) ] }

答案 2 :(得分:29)

这是Josh Nichols的fantastic post,它解释了如何做你所要求的。

总结一下,这里是他的代码:

csv = CSV.new(body, :headers => true, :header_converters => :symbol, :converters => [:all, :blank_to_nil])
csv.to_a.map {|row| row.to_hash }
=> [{:year=>1997, :make=>"Ford", :model=>"E350", :description=>"ac, abs, moon", :price=>3000.0}, {:year=>1999, :make=>"Chevy", :model=>"Venture \"Extended Edition\"", :description=>nil, :price=>4900.0}, {:year=>1999, :make=>"Chevy", :model=>"Venture \"Extended Edition, Very Large\"", :description=>nil, :price=>5000.0}, {:year=>1996, :make=>"Jeep", :model=>"Grand Cherokee", :description=>"MUST SELL!\nair, moon roof, loaded", :price=>4799.0}]

因此,您可以将CSV文件的正文保存到名为body的字符串中。

body = "09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5"

然后运行上面列出的代码。

答案 3 :(得分:5)

Nathan Long的答案略有不同

data_file = './sheet.csv'
data = []
CSV.foreach(data_file, headers: true) do |row|
  data << row.to_hash
end

现在data是一系列哈希值,用来进行出价!

答案 4 :(得分:2)

CSV模块的headers选项接受一个字符串数组,当它们不作为CSV内容的第一行出现时,将用作标题。

CSV.parse(content, headers: %w(time number team_1 team_2 score))

这将使用给定的标题作为键生成一个可枚举的哈希值。

答案 5 :(得分:1)

您也可以尝试使用以下gem:

&#xA;&#xA;
  require'csv_hasher'&#xA; arr_of_hashes = CSVHasher.hashify('/ path / to / csv / file')&#xA;  
&#xA;&#xA;

返回的哈希的键将是csv文件的标题值。

&#xA; &#xA;

如果你想传递自己的密钥,那么

&#xA;&#xA;
  keys = [:key1,:key2,...]&#xA ; arr_of_hashers = CSVHasher.hashify('/ path / to / csv / file',{keys:keys})&#xA;  
&#xA;