假设我有一个包含4个字段的CSV文件,
ID,name,pay,age
和大约32,000条记录。
在Ruby中将其粘贴到哈希中的最佳方法是什么?
换句话说,示例记录如下:
{:rec1 => {:id =>“00001”,:name => “Bob”,:pay => 150,:age => 95}}
感谢您的帮助!
答案 0 :(得分:5)
您可以使用Excelsior
rubygem:
csv = ...
result = Hash.new
counter = 1
Excelsior::Reader.rows(csv) do |row|
row_hash = result[("rec#{counter}".intern)] = Hash.new
row.each do |col_name, col_val|
row_hash[col_name.intern] = col_val
end
counter += 1
end
# do something with result...
答案 1 :(得分:3)
通常我们希望对Hash键使用:id
字段,因为它与数据库表中的主键相同:
{"00001" => {:name => "Bob", :pay => 150, :age => 95 } }
这将创建一个类似的哈希:
require 'ap'
# Pretend this is CSV data...
csv = [
%w[ id name pay age ],
%w[ 1 bob 150 95 ],
%w[ 2 fred 151 90 ],
%w[ 3 sam 140 85 ],
%w[ 31999 jane 150 95 ]
]
# pull headers from the first record
headers = csv.shift
# drop the first header, which is the ID. We'll use it as the key so we won't need a name for it.
headers.shift
# loop over the remaining records, adding them to a hash
data = csv.inject({}) { |h, row| h[row.shift.rjust(5, '0')] = Hash[headers.zip(row)]; h }
ap data
# >> {
# >> "00001" => {
# >> "name" => "bob",
# >> "pay" => "150",
# >> "age" => "95"
# >> },
# >> "00002" => {
# >> "name" => "fred",
# >> "pay" => "151",
# >> "age" => "90"
# >> },
# >> "00003" => {
# >> "name" => "sam",
# >> "pay" => "140",
# >> "age" => "85"
# >> },
# >> "31999" => {
# >> "name" => "jane",
# >> "pay" => "150",
# >> "age" => "95"
# >> }
# >> }
答案 2 :(得分:1)
查看Ruby Gem smarter_csv
,它解析CSV文件并返回CSV文件中行的哈希数组。它还可以进行分块,以更有效地处理大型CSV文件,因此您可以将块传递给并行的Resque worker或使用Mongoid或MongoMapper批量创建记录。
它提供了大量有用的选项 - 查看GitHub
上的文档require 'smarter_csv'
filename = '/tmp/input.csv'
array = SmarterCSV.process(filename)
=>
[ {:id=> 1, :name => "Bob", :pay => 150, :age => 95 } ,
...
]
另见:
答案 3 :(得分:0)
Hash[*CSV.read(filename, :headers => true).flat_map.with_index{|r,i| ["rec#{i+1}", r.to_hash]}]