この記事では、RubyでCSVファイルの読み込み方法を解説していきます。
システム開発において、CSVファイルを入出力することは多々あり、システム間でデータをやり取りするときや、画面に表示されている一覧データをエクスポートする時などにCSVファイルを使用します。
Rubyでは、csvライブラリを使うことで簡単にCSVファイルの読み込みが行えます。
では、RubyでCSVファイルを読み込み方法を見ていきましょう。
CSVとは?
CSVはComma Separated Valueの略で、その名の通り、項目をカンマで区切ったファイルです。データが複数ある場合は、改行して複数行に渡って記述します。
以下は、実際のCSVファイルの例です。
id, name, age
1, 山田, 20
10001, 鈴木, 30
3, 伊藤, 40
Rubyのcsvライブラリには、CSVファイルを読み込むメソッドとして大きくCSV.readとCSV.foreachメソッドの2つがあります。
それぞれのメソッドの使い方について、見ていきましょう。
「CSV.read」メソッドでCSVを読み込む
最初は、CSV.readメソッドの使い方を見ていきましょう。
CSV.readメソッドは、指定パスのふCSVファイルの内容を変数の中に一気に読み込むメソッドで、次のように使用します。
require "csv"
## 読み込みを行うテスト用のCSVファイルを作成
File.write("users.csv", <<CSV)
id,name,age,address
1,山田,20,TOKYO
2,鈴木,18,NAGOYA
3,伊藤,19,OSAKA
4,佐藤,21,KANAGAWA
CSV
## 上で作成したCSVファイルを「CSV.read」メソッドで読み込み
table = CSV.read("users.csv", headers: true)
## 読み込んだCSVの行数の数だけ処理を繰り返す
table.each do |row|
## row["列名"]で値が取得できる
id = row["id"]
name = row["name"]
age = row["age"]
address = row["address"]
end
このように、CSV.readメソッドを使用すると、簡単なコードでCSVファイルの読み込みが行え、row[“name”]のように列名で値を取得できるため、直感的で保守性が高いコードが組めます。
列名で値が取得できるもう一つのメリットとして、例えばageとaddress列の順序が入れ替わったりした場合でも、既存のロジックを修正しなくて済むため、拡張性が高いコードを組めるということになります。
ヘッダ行が無いCSVファイルを読み込む
ヘッダ行が無い、データのみのCSVファイルを読み込む場合は、列名が分からないためrow[“列名”]のようにCSVのデータにアクセスすることができません。
ヘッダ無しのCSVファイルの読み方も見ていきましょう。
まず、ヘッダ行が無いCSVの場合は、CSV.readメソッドのheadersオプションにfalseを指定します。
array = CSV.read("users.csv", headers: false)
headersオプションにfalseを指定すると、CSV.readメソッドの戻り値は配列(Aarra)になるため、CSVの各項目にアクセスするときは、0〜のインデックスでアクセスします。
array.each do |row|
## row[インデックス]で値を取得する
id = row[0]
name = row[1]
age = row[2]
address = row[3]
end
ダブルクォーテーションで囲われた文字も難なく読める
一般的なCSVでは、文字列はダブルクォーテーションで囲われていることが多いです。
csvライブラリでは、ダブルクォーテーションで囲われた文字を自動で判別して読み込んでくれるため、ダブルクォーテーションの有無を気にすることなくCSVのデータを読み込むことができます。
実際に以下のように、文字列をダブルクォーテーション囲ったCSVファイルを用意して試してみましょう。
1,"山田",20,"TOKYO"
2,"鈴木",18,"NAGOYA"
3,"伊藤",19,"OSAKA"
以下が、サンプルコードと実行結果です。
table = CSV.read("users.csv", headers: false)
table.each do |row|
p "[0]=%s, [1]=%s, [2]=%s, [3]=%s" % [ row[0], row[1], row[2], row[3] ]
end
【実行結果】
-----------------------------------
[0]=1, [1]=山田, [2]=20, [3]=TOKYO
[0]=2, [1]=鈴木, [2]=18, [3]=NAGOYA
[0]=3, [1]=伊藤, [2]=19, [3]=OSAKA
このように、ダブルクォーテーションの有無に関わらず、同じコードでCSVファイルを読み込むことができます。
エンコーディングを指定して読み込む
エンコーディングを指定してCSVファイルの読み込みを行う場合は、encodingオプションを指定します。
エンコーディングの指定を省略した場合は、デフォルトのutf-8″が適用されます。
CSV.open('Sample.csv','w', :encoding => "utf-8")
「CSV.foreach」メソッドでCSVを読み込む
次は、CSV.foreachメソッドでCSVファイル読み込む方法を解説します。
CSV.foreachメソッドは、CSVファイルから1ずつ行(データ)を読み込むため、大量のデータが格納されたCSVファイルを読み込む時に向いているメソッドです。
CSV.foreach の使い方
CSV.foreachメソッドは、引数に読み込むCSVファイルのパスを指定し、各行が与えられたブロックで処理を行います。
## 読み込みを行うテスト用のCSVファイルを作成
File.write("users.csv", <<CSV)
id,name,age,address
1,山田,20,TOKYO
2,鈴木,18,NAGOYA
3,伊藤,19,OSAKA
CSV
CSV.foreach("users.csv", headers: true) do |row|
# 行に対する処理
name = row["name"] ## name列の値を取得
end
ヘッダー有無の指定
CSV.readメソッド同様、CSV.foreachでもオプションでヘッダの有無を指定して、CSVファイルを読み込むことができます。
CSV.foreach("users.csv", headers: false) do |row|
## row[インデックス]で値を取得する
id = row[0]
name = row[1]
end
エンコーディングを指定してCSVを読み込み
エンコーディングの指定も、CSV.readメソッド同様にencodingオプションを指定します。
エンコーディングの指定を省略した場合は、デフォルトのutf-8″が適用されます。
CSV.foreach("users.csv", :encoding => "utf-8") do |row|
RubyでのCSVファイル読み込みは簡単
RubyでCSVファイルの読み込み方法を解説してきました。
標準のcsvライブラリが便利で使いやすいため、Rubyでは簡単なコードでCSVファイルの読み書きができます。
【関連記事】
▶【Rubyの基礎】配列の検索で使われるfindメソッドの使い方
CSVのファイル形式は、RFC4180「Common Format and MIME Type for Comma-Separated Values (CSV) Files」で規定されているため、興味がある方は以下のURLもご覧ください。
https://www.ietf.org/rfc/rfc4180.txt