Ruby: how to use dump method to output data to csv file?

I am trying to use the standard csv lib ruby ​​to unload the arr of an object in a csv.file called 'a.csv'

http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html#method-c-dump

dump(ary_of_objs, io = "", options = Hash.new) 

but in this method, how can I dump a file? There are no such examples and does not help. I google this is not an example for me ...

In addition, documents reported that ...

The next method you can provide is an instance method called csv_headers (). This method is expected to return the second row of the document (again, as an array), which should be used for each column header. By default, :: load will set the instance variable if the field header begins with the @ symbol or a send () call that passes both the method name and the field value as an argument. This method is called only for the first array object.

Does anyone know how to pass the csv_headers () instance method to this dump function?

+4
source share
2 answers

I have not tested this yet, but it looks like io should be installed in a file. According to the document, you linked "The io parameter can be used to serialize to a file"

Sort of:
f = File.open("filename")
dump(ary_of_objs, io = f, options = Hash.new)

+3
source

The accepted answer really does not answer the question, so I thought that I was giving a useful example.

First of all, if you look at the docs at http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html , if you hover the method name for dump , you will see that you can click to show source . If you do this, you will see that the dump method tries to call csv_headers on the first object that you pass from ary_of_objs :

 obj_template = ary_of_objs.first ...snip... headers = obj_template.csv_headers 

Then you will see that the method will call csv_dump for each object in ary_of_objs and pass it to headers :

 ary_of_objs.each do |obj| begin csv << obj.csv_dump(headers) rescue NoMethodError csv << headers.map do |var| if var[0] == @ obj.instance_variable_get(var) else obj[var[0..-2]] end end end end 

Therefore, we need to increase each entry in array_of_objs in order to answer these two methods. Here is an example of a wrapper class that will accept Hash and return the hash keys as CSV headers, and then be able to flush each line based on the headers.

 class CsvRowDump def initialize(row_hash) @row = row_hash end def csv_headers @row.keys end def csv_dump(headers) headers.map { |h| @row[h] } end end 

There’s another catch. This dump method wants to write an extra line at the top of the CSV file before the headers, and there is no way to skip this if you call this method because of this code at the top:

  # write meta information begin csv << obj_template.class.csv_meta rescue NoMethodError csv << [:class, obj_template.class] end 

Even if you return '' from CsvRowDump.csv_meta , which will still be the empty string where the parsing awaits the headers. So instead, let dump write this line and then delete it after calling dump . This example assumes that you have an array of hashes, all of which have the same keys (which will be the CSV header).

 @rows = @hashes.map { |h| CsvRowDump.new(h) } File.open(@filename, "wb") do |f| str = CSV::dump(@rows) f.write(str.split(/\n/)[1..-1].join("\n")) end 
+2
source

Source: https://habr.com/ru/post/1415505/


All Articles