2016-08-21 92 views
6

我需要將CSV數組中的哈希值轉換爲數組。各種方法,我發現涉及數組中插入的哈希值:在ruby中智能地將散列數組轉換爲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 :

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

我正在尋找一種方式來創建查找所有可能的標題,並指定在正確的順序值,增加空的空間,其中需要一個CSV文件。

回答

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類看一看。我發現他們很方便。