Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby哈希中存储CSV数据_Ruby_Hash - Fatal编程技术网

在Ruby哈希中存储CSV数据

在Ruby哈希中存储CSV数据,ruby,hash,Ruby,Hash,假设我有一个包含4个字段的CSV文件 ID,name,pay,age 和大约32000张唱片 在Ruby中,将其粘贴到哈希中的最佳方法是什么 换句话说,示例记录如下所示: {:rec1=>{:id=>“00001”,:name=>“Bob”,:pay=>150,:age=>95}} 谢谢你的帮助 您可以使用rubygem进行以下操作: csv = ... result = Hash.new counter = 1 Excelsior::Reader.rows(csv) do |row|

假设我有一个包含4个字段的CSV文件

ID,name,pay,age
和大约32000张唱片

在Ruby中,将其粘贴到哈希中的最佳方法是什么

换句话说,示例记录如下所示:

{:rec1=>{:id=>“00001”,:name=>“Bob”,:pay=>150,:age=>95}}

谢谢你的帮助

您可以使用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...

通常,我们希望对散列键使用
: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"
# >>     }
# >> }

查看Ruby Gem
smarter_csv
,它解析csv文件并返回csv文件中行的哈希数组。它还可以进行分块,以更有效地处理大型CSV文件,因此您可以将分块传递给并行重新创建工作人员,或使用Mongoid或MongoMapper批量创建记录

它提供了大量有用的选项-请查看

另见:


这不是一种可扩展的做法。使用Postgres、MySQL甚至SQLite的简单数据库至少可以使用Ruby DBI或类似于ORM的Sequel、ActiveRecord或Datamapper轻松构建和访问。它们不会像内存中的散列那样快,但它们的可伸缩性要高得多。@Greg,我知道它的可伸缩性不是特别强,但因为数据集的大小相对固定,而且现在很小,所以应该没问题。也感谢您的以下解决方案:-)@mbm最好的方法是使用
smarter\u csv
gem-查看我的答案below@JacobRelkin
Excelsior
很不错,但我还是喜欢
smarter\u csv
更好的功能。
require 'smarter_csv'
filename = '/tmp/input.csv'
array = SmarterCSV.process(filename)

=>

[ {:id=> 1, :name => "Bob", :pay => 150, :age => 95 } ,
 ...
]
Hash[*CSV.read(filename, :headers => true).flat_map.with_index{|r,i| ["rec#{i+1}", r.to_hash]}]