2016-08-21 19 views
6

Potrzebuję przekonwertować tablicę skrótów w pliku CSV. Różne metody I znaleziono obejmować wstawianie w tablicy wartości skrótu:Sprytnie konwertująca tablica skrótów do CSV w Ruby

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 

Niestety sposób ten wymaga, aby każdy element tablicy jest pełna, na przykład kiedy ma tę tablicę to nawet nie zwraca ważnego csv :

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

Szukam sposobu, aby stworzyć CSV, który wyszukuje wszystkie możliwe nagłówki i przypisuje wartości w odpowiedniej kolejności, dodawanie pustych przestrzeni w razie potrzeby.

Odpowiedz

9

Co o:

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

dokładnie to, co potrzebne. Dziękuję Ci! – TopperH

3

Zrobiłbym to w ten sposób. To dość brutalna siła, ponieważ musi znaleźć wszystkie nagłówki, które istnieją, a także musi wypełnić puste elementy ..

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 

Spójrz na CSV::Row i CSV::Table klas. Uważam, że są przydatne.