LoginSignup
21
13

More than 5 years have passed since last update.

Ruby Array of HashをCSVに変換

Posted at

以下のように順番も必須項目もばらばらのハッシュ配列を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]
21
13
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
13