Use FasterCSV or Ruby 1.9's CSV library
Rubyベストプラクティス -プロフェッショナルによるコードとテクニック
- 作者: Gregory Brown,高橋征義,笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/03/26
- メディア: 大型本
- 購入: 9人 クリック: 307回
- この商品を含むブログ (47件) を見る
を読んでいたら、標準CSV ライブラリの紹介が載っていた。知らなかったのだけれど、CSV ライブラリは1.9 系でFasterCSV に置き換えられたとのこと。
1.8 系以前のCSV ライブラリはそこまで使いやすいって感じじゃなかった。けれど、FasterCSV、1.9 系のCSV ライブラリを使うことで、CSV の操作をずっと簡単に行えることができるようになる!
CSV 形式のファイルを読み込む
例えば、ヘッダつきのCSV ファイルを読み込むなら、次のように書く必要があった。
require 'csv' csv = CSV::Reader.parse(DATA) header = nil csv.inject([]) do |result, line| unless header header = line else result.push Hash[*header.zip(line).flatten] end result end __END__ id,name,age 1,kai,19 2,hong,20 3,bob,
これが、FasterCSV(または1.9 系のCSV) を使うと次のように書けるようになる。(DATA の内容は先のDATA の内容と同じ)
require 'rubygems' require 'fastercsv' require 'ruby-debug' csv = FasterCSV.new(DATA, :headers => true, :header_converters => :symbol) csv.first[:id] # => "1" csv.first[:age] # => "20"
また、属性値を変換するConverter も指定することができる。ライブラリには日付と数値の属性値を変換するConverter が含まれていて、その他自分で作成したConverter も簡単に組み込める。
例えば、数値に変換できる値を変換するには、Converter として:integer を指定する。
csv = FasterCSV.new(DATA, :headers => true, :header_converters => :symbol, :converters => :integer) csv.first[:id] # => 1 csv.first[:age] # => 20
CSV 形式のファイルを書き出す
書き出す場合も、以前のCSV ライブラリだと使いにくい部分があって、例えば以下のように使えるラッパーをつくってた。
User = Struct.new(:id, :name, :age) elements = [ User.new(1, 'kai', 19), User.new(2, 'hong', 20) ] FileUtility.to_csv(elements, :header => %w[id name age]) do |e| [ e.id, e.name, e.age ] end # => "id,name,age\n1,kai,19\2,hong,20\n"
この場合も、FasterCSV なら次のように書ける。
FasterCSV.generate(:headers => %w[id name age], :write_headers => true){|csv| elements.inject(csv){|c, e| c << e c } } # => "id,name,age\n1,kai,19\2,hong,20\n"