我有很多哈希,比如这个
# note that the key order isn't consistent
data = [
{foo: 1, bar: 2, baz: 3},
{foo: 11, baz: 33, bar: 22}
]
我想将其变成CSV
foo,bar,baz
1,2,3
11,22,33
我这样做:
columns = [:foo, :bar, :baz]
csv_string = CSV.generate do |csv|
csv << columns
data.each do |d|
row = []
columns.each do |column|
row << d[column]
end
csv << row
end
end
有更好的方法吗?我想做的是像......
csv_string = CSV.generate do |csv|
csv << [:foo, :bar, :baz]
data.each do |row|
csv.add_row_hash row
end
end
答案 0 :(得分:2)
通过传递给生成的相应选项,您可以实现您想要的效果。请注意,一旦设置了标题,您就可以将哈希直接添加到CSV中。
c = CSV.generate(:headers => [:foo, :bar, :baz], :write_headers => true) do |csv|
data.each { |row| csv << row }
end
输出:
foo,bar,baz
1,2,3
11,22,33
答案 1 :(得分:1)
如果密钥丢失,您需要获取所有可能的密钥
keys = data.map(&:keys).flatten.uniq
然后使用这些键映射每一行。
csv_string = CSV.generate do |csv|
csv << keys
data.each do |row|
csv << row.values_at(keys)
end
end
答案 2 :(得分:-1)
我的第一个想法:您的data
可用于将数据插入数据库表。
如果将其与csv-output of a DB-table结合使用,则可以使用其他解决方案。
示例:
data = [
{foo: 1, bar: 2, baz: 3},
{foo: 11, baz: 33, bar: 22},
{foo: 11, baz: 33, bar: 22, xx: 3}, #additional parameters are no problem
]
#Prepare DB as a helper
require 'sequel'
DB = Sequel.sqlite
DB.extension(:sequel_3_dataset_methods) #define to_csv
DB.create_table(:tab){
add_column :foo
add_column :bar
add_column :baz
}
DB[:tab].multi_insert(data) #fill table
#output as csv (the gsub is necessary on Windows, maybe not necessary on other OS
puts DB[:tab].to_csv.gsub("\r\n","\n")
缺点:你需要续集
优势:您可以非常轻松地调整订单:
puts DB[:tab].select(:bar, :baz).to_csv.gsub("\r\n","\n")