web-dev-qa-db-ja.com

CSVファイルをハッシュの配列に変換します

私は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"]のようにアクセスできる必要があります。 CSVFasterCSVよりもsplitクラスの方が好きです。同様の問題が解決されたスレッドを表示したり、スレッドにリダイレクトしたりできますか?

37
Mythago

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) ] }
36
AJcodez

headers: true

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

そこから、好きなようにハッシュを操作できます。

(Ruby 2.0でテストしましたが、これはかなり前から機能していると思います。)

編集

あなたはヘッダーを持っていないと言います-それらを読んだ後、ファイルの内容の先頭にヘッダー行を追加できますか?

69
Nathan Long

これは、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"

そして、その上で上記のコードを実行します。

29
CodeBiker

少し短いソリューション

文字列の解析:

CSV.parse(content, headers: :first_row).map(&:to_h)

解析ファイル:

CSV.open(filename, headers: :first_row).map(&:to_h)
15

Nathan Long の答えのわずかな変動

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

dataは、入札を行うためのハッシュの配列です!

5
lacostenycoder

CSVモジュールのheadersオプションは、CSVコンテンツの最初の行として存在しない場合、ヘッダーとして使用される文字列の配列を受け入れます。

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

これは、指定されたヘッダーをキーとして使用してハッシュの列挙可能なものを生成します。

2
Will Madden

また、次の宝石を試すことができます

require 'csv_hasher'
arr_of_hashes = CSVHasher.hashify('/path/to/csv/file')

返されるハッシュのキーは、csvファイルのヘッダー値になります。

独自のキーを渡したい場合

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