以下のように順番も必須項目もばらばらのハッシュ配列をCSVに変換したい.
[
{ name: "Newton", age: 84, from: "England", gender: "male" },
{ name: "Planck", age: 89, role: "physicist" },
{ from: "Russia", age: 53, name: "Tchaikovsky", role: "composer" },
{ from: "Czech", name: "Nedved", tel: "00-0000-0000", role: "soccer player" },
]
想定の変換CSV
name,age,from,gender,role,tel
Newton,84,England,male,,
Planck,89,,,physicist,
Tchaikovsky,53,Russia,,composer,
Nedved,,Czech,,soccer player,00-0000-0000
ざっと探したところ標準の方法はないみたいだったので作った.
def hash_list_to_csv_array( list, key_order=nil )
key_order ||= list.map(&:keys).flatten.uniq
arr = list.map do |hash|
key_order.map{|key| hash[key]}
end
arr.unshift(key_order)
end
require "csv"
list = [
{ name: "Newton", age: 84, from: "England", gender: "male" },
{ name: "Planck", age: 89, role: "physicist" },
{ from: "Russia", age: 53, name: "Tchaikovsky", role: "composer" },
{ from: "Czech", name: "Nedved", tel: "00-0000-0000", role: "soccer player" },
]
puts hash_list_to_csv_array( list ).map(&:to_csv).join
# name,age,from,gender,role,tel
# Newton,84,England,male,,
# Planck,89,,,physicist,
# Tchaikovsky,53,Russia,,composer,
# Nedved,,Czech,,soccer player,00-0000-0000
# キーの並びと項目を明示指定したいときは第2引数に指定
puts hash_list_to_csv_array( list, [:role,:name] ).map(&:to_csv).join
# role,name
# ,Newton
# physicist,Planck
# composer,Tchaikovsky
# soccer player,Nedved
Environment
% ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]