我尝试使用ruby标准csv lib将对象的arr转储到csv.file,称为'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)
但是在这种方法中,我如何转储到文件中? 没有这样的例子存在和帮助。我谷歌没有为我做的例子...
此外,文档说......
您可以提供的下一个方法是调用实例方法 csv_headers()。预计此方法将返回第二行 文档(再次作为数组),用于给每个文档 列标题。默认情况下,:: load将设置实例变量if 字段标题以@字符开头或调用send()传递 header作为方法名称,字段值作为参数。这个 method仅在Array的第一个对象上调用。
任何人都知道如何将实例方法csv_headers()传递给此转储函数?
答案 0 :(得分:3)
我还没有测试过,但看起来应该将io设置为文件。根据您链接的文档“io参数可用于序列化为文件”
类似的东西:
f = File.open("filename")
dump(ary_of_objs, io = f, options = Hash.new)
答案 1 :(得分:2)
接受的答案并没有真正回答这个问题,所以我想我会给出一个有用的例子。
首先,如果您查看http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html处的文档,如果将鼠标悬停在dump
的方法名称上,则表明您可以click to show source
。如果您这样做,您会看到dump
方法尝试在您从csv_headers
传入的第一个对象上调用ary_of_objs
:
obj_template = ary_of_objs.first
...snip...
headers = obj_template.csv_headers
之后您会看到该方法会在csv_dump
中的每个对象上调用ary_of_objs
并传入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
因此我们需要扩充array_of_objs
中的每个条目以响应这两种方法。这是一个示例包装器类,它将采用Hash
,并将散列键作为CSV标头返回,然后能够根据标头转储每一行。
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
还有一个问题。这个dump
方法想要在标题之前在CSV文件的顶部写一个额外的行,如果由于此代码在顶部调用此方法,则无法跳过该行:
# write meta information
begin
csv << obj_template.class.csv_meta
rescue NoMethodError
csv << [:class, obj_template.class]
end
即使你从CsvRowDump.csv_meta
返回''仍然是一个空白行,其中一个解析器需要标题。因此,让我们让dump
写下该行,然后在我们调用dump
时将其删除。此示例假设您有一个哈希数组,这些哈希都具有相同的键(将是CSV标题)。
@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