2016-08-21 16 views
6

ハッシュの配列をCSVファイルに変換する必要があります。ハッシュの配列をルビーのCSVにスマートに変換する

class Array 
    def to_csv(csv_filename="hash.csv") 
    require 'csv' 
    CSV.open(csv_filename, "wb") do |csv| 
     csv << first.keys # adds the attributes name on the first line 
     self.each do |hash| 
     csv << hash.values 
     end 
    end 
    end 
end 

残念ながら、この方法は、配列の各要素が、私はこの配列を持っている場合例えば、それも有効なCSVファイルを返しません、完全であることが必要です。私は、配列のハッシュ値に挿入関与した様々な方法:私はすべての可能なヘッダを見つけ、必要な場合に空のスペースを追加し、正しい順序で値を代入したCSVを作成する方法を探しています

myarray = [ 
    {foo: 1, bar: 2, baz: 3}, 
    {bar: 2, baz: 3}, 
    {foo: 2, bar: 4, baz: 9, zab: 44} 
] 

答えて

9

何について:私がまさに必要

class Array 
    def to_csv(csv_filename="hash.csv") 
    require 'csv' 
    # Get all unique keys into an array: 
    keys = self.flat_map(&:keys).uniq 
    CSV.open(csv_filename, "wb") do |csv| 
     csv << keys 
     self.each do |hash| 
     # fetch values at keys location, inserting null if not found. 
     csv << hash.values_at(*keys) 
     end 
    end 
    end 
end 
+0

。ありがとうございました! – TopperH

3

私はこのようにします。それが存在しても、空の要素を埋めるために必要なすべてのヘッダーを見つける必要があるので、それは

class Array 
    def to_csv(csv_filename='test.csv') 
    require 'csv' 

    headers = [] 
    self.each {|hash| headers += hash.keys} 
    headers = headers.uniq 

    rows = [] 
    self.each do |hash| 
     arr_row = [] 
     headers.each {|header| arr_row.push(hash.key?(header) ? hash[header] : nil)} 
     csv_row = CSV::Row.new(headers, arr_row) 
     rows.push(csv_row) 
    end 
    csv_table = CSV::Table.new(rows) 
    File.open(csv_filename, 'w'){|file| file << csv_table.to_s} 
    end 
end 

CSV::RowCSV::Tableクラスを見てみましょう。..かなり強引です。私はそれらを便利だと思う。

関連する問題