巧妙地将Ruby中的哈希数组转换为CSV

6
我需要将一个哈希数组转换为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文件的方法,该文件可以查找所有可能的标题,并将值按正确顺序分配,在需要时添加空格。
2个回答

13

怎么样:

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

正是我所需要的。谢谢! - 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类。我觉得它们很方便。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接