CSVファイルを解析して、各行がオブジェクトのように扱われ、ヘッダー行がオブジェクトの属性の名前になるようにします。私はこれを書くことができましたが、すでにそこにあると確信しています。
ここに私のCSV入力があります:
"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
コードは次のようになります。
CSV.open('my_file.csv','r') do |csv_obj|
puts csv_obj.foo #prints 1 the 1st time, "blah" 2nd time, etc
puts csv.bar #prints 2 the first time, 7 the 2nd time, etc
end
RubyのCSVモジュールを使用すると、インデックスでのみフィールドにアクセスできます。上記のコードはもう少し読みやすいと思います。何か案は?
Ruby 1.9以降を使用すると、インデックス付け可能なオブジェクトを取得できます。
CSV.foreach('my_file.csv', :headers => true) do |row|
puts row['foo'] # prints 1 the 1st time, "blah" 2nd time, etc
puts row['bar'] # prints 2 the first time, 7 the 2nd time, etc
end
ドット構文ではありませんが、数値インデックスよりも作業する方がはるかに優れています。
余談ですが、for Ruby 1.8.x FasterCSV は、上記の構文を使用するために必要なものです。
Ruby 1.9を使用したシンボリック構文の例を次に示します。以下の例では、コードはRails dbディレクトリからdata.csvという名前のCSVファイルを読み取ります。
:headers => true
は、最初の行をデータ行ではなくヘッダーとして扱います。 :header_converters => :symbolize
パラメーターは、ヘッダー行の各セルをRubyシンボルに変換します。
CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end
Ruby 1.8の場合:
require 'fastercsv'
CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end
Poul(StackOverflow asker)が提供するCSVに基づくと、上記のサンプルコードの出力は次のようになります。
1,2,3
blah,7,blam
4,5,6
CSVファイルのヘッダーで使用される文字によっては、CSV(FasterCSV)が文字列ヘッダーをシンボルに変換する方法を確認するために、ヘッダーを出力する必要がある場合があります。 CSV.foreach
内からヘッダーの配列を出力できます。
row.headers
Ruby 2.3:でハッシュを取得するのは簡単
CSV.foreach('my_file.csv', headers: true, header_converters: :symbol) do |row|
puts row.to_h[:foo]
puts row.to_h[:bar]
end
私は議論にかなり遅れましたが、数か月前に https://github.com/vicentereig/virgola で「CSV to object mapper」を開始しました。
CSVコンテンツを考えると、それらをFooBar
オブジェクトの配列にマッピングするのは非常に簡単です:
"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
require 'virgola'
class FooBar
include Virgola
attribute :foo
attribute :bar
attribute :baz
end
csv = <<CSV
"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
CSV
foo_bars = FooBar.parse(csv).all
foo_bars.each { |foo_bar| puts foo_bar.foo, foo_bar.bar, foo_bar.baz }
私はいくつかの頻度でこの質問に答えたので
array_of_hashmaps = CSV.read("path/to/file.csv", headers: true)
puts array_of_hashmaps.first["foo"] # 1
これは、ファイル全体を丸lurみしたい場合の非ブロックバージョンです。