问题:
我有以下哈希: hash = {1 => {:price =>“400”,:brand =>“Primark”},2 => {:price =>“1000”, :brand =>“pull& bear”},3 => {:price =>“1700”,:brand =>“”}, 4 => {:price =>“500”,:brand => …
您似乎只对嵌套哈希的值感兴趣。在这种情况下,你可以做到
titles = hash.values.map(&:keys).flatten.uniq rows = hash.values.map { |data| data.values_at(*titles) } s = CSV.generate do |csv| csv << titles rows.each do |row| csv << row end end
(更新)
标题应该扁平化为一个简单的数组。
CSV格式本质上是一个数组数组。主阵列的每个元素都是一行。单行是一组单元格。所以你想要的基本上是这样的:
[ [:price, :brand], ["400", "Primark"], ["1000", "Pull&Bear"] ]
您可以通过以下方式实现它:
headers = hash.values[0].keys # this will return [:price, :brand] and we'll use it as a header data = hash.values.map(&:values) csv_output = CSV.generate do |csv| csv << headers # we need headers only once, we don't need them in every row data.each do |single_row| # iterate over each row csv << single_row # add the row to csv file end end File.write('the_file.csv', csv_output)
此代码假定对于每一行,您将拥有所有可用数据(即每行将提供价格和品牌)。用户重写提供的上述代码更加灵活。
我会做这样的事情:
require 'csv' CSV.open('the_file.csv', 'w') do |csv| hash.each do |id, attributes| csv << [id, *attributes.values_at(:price, :brand)] end end