简体   繁体   中英

convert array of hashes to csv file

How do you convert an array of hashes to a .csv file?

I have tried

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

but it is blank

Try this:

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

If you want the first line of the CSV to contain the keys of the hash (a header row), simply do:

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

Please read the comment of @cgenco below: He wrote a monkey patch for the Array class.

CSV is smart enough to deal with the non-uniform hashes for you. See the code for CSV::Writer#<<

So, this works, and is a bit simpler than the above examples:

CSV.open("data.csv", "wb", {headers: @data.first.keys} ) do |csv|
  @data.each do |hash|
    csv << hash
  end
end

If the hashes aren't uniform then you will end up with data in the wrong columns. You should use values_at instead:

CSV.open("data.csv", "wb") do |csv|
  keys = @data.first.keys
  csv << keys
  @data.each do |hash|
    csv << hash.values_at(*keys)
  end
end

If the keys are not the same in all rows, the current answers fail. This is the safest approach:

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)
  }
}

All keys will be present in the CSV, even if they don't appear in the first row:

a b c
1 2
3 4

None of the other answers worked for me for one reason or another, so I'll throw in my contribution as well. Here's what worked for me for my array of hashes with 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM