24

如何将散列数组转换为 .csv 文件?

我努力了

    CSV.open("data.csv", "wb") do |csv|
      @data.to_csv
    end

但它是空白的

4

5 回答 5

56

尝试这个:

CSV.open("data.csv", "wb") do |csv|
  @data.each do |hash|
    csv << hash.values
  end
end

如果您希望 CSV 的第一行包含哈希键(标题行),只需执行以下操作:

CSV.open("data.csv", "wb") do |csv|
  csv << @data.first.keys # adds the attributes name on the first line
  @data.each do |hash|
    csv << hash.values
  end
end

请阅读下面@cgenco 的评论:他为 Array 类编写了一个猴子补丁。

于 2013-06-26T16:40:35.660 回答
5

CSV足够聪明,可以为您处理非均匀哈希。请参阅CSV::Writer#<<的代码

所以,这很有效,并且比上面的例子简单一点:

CSV.open("data.csv", "wb", {headers: @data.first.keys} ) do |csv|
  @data.each do |hash|
    csv << hash
  end
end
于 2019-09-20T13:55:28.493 回答
4

如果散列不统一,那么您最终会得到错误列中的数据。您应该改用 values_at :

CSV.open("data.csv", "wb") do |csv|
  keys = @data.first.keys
  csv << keys
  @data.each do |hash|
    csv << hash.values_at(*keys)
  end
end
于 2019-01-13T08:17:38.783 回答
2

如果所有行中的键都不相同,则当前答案失败。这是最安全的方法:

data = [{a: 1, b: 2}, {b: 3, c: 4}]

CSV.open("data.csv", "w") { |csv|
  headers = data.flat_map(&:keys).uniq
  csv << headers
  data.each { |row|
    csv << row.values_at(*headers)
  }
}

所有键都将出现在 CSV 中,即使它们没有出现在第一行中:

一个 b C
1 2
3 4
于 2021-03-03T13:37:41.020 回答
0

出于某种原因,其他答案都没有对我有用,所以我也会做出贡献。这对我使用 ruby​​ 2.7 的哈希数组有用:

headers = data.map(&:keys).flatten.uniq
CSV.open("data.csv", "wb", {headers: headers} ) do |csv|
  csv << headers

  data.each do |hash|
    csv << hash
  end
end
于 2021-04-16T19:06:38.030 回答