【问题标题】:Smartly converting array of hashes to CSV in ruby在 ruby​​ 中智能地将哈希数组转换为 CSV
【发布时间】:2016-08-22 01:54:30
【问题描述】:

我需要在 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,它可以找到所有可能的标题,并以正确的顺序分配值,在需要的地方添加空格。

【问题讨论】:

    标签: arrays ruby csv


    【解决方案1】:

    怎么样:

    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
    

    【讨论】:

    • 正是我需要的。谢谢!
    【解决方案2】:

    我会这样做。这是相当蛮力的,因为它需要找到所有存在的标题并且还需要填充空元素..

    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 类。我觉得它们很方便。

    【讨论】:

      猜你喜欢
      • 2010-12-11
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2017-07-06
      相关资源
      最近更新 更多