TopperH TopperH - 3 months ago 43
Ruby Question

Smartly converting array of hashes to CSV in ruby

I need to convert an array of hashes in a CSV file. The various methods I found involve inserting in the array the hash values:

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


Unfortunately this method requires that each element in the array is complete, for example when I have this array it won't even return a valid csv:

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


I'm looking for a way to create a csv that finds all the possible headers, and assigns the values in correct order, adding empty spaces where needed.

Answer

What about:

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
Comments