【问题标题】:Ruby: how can use the dump method to output data to a csv file?Ruby:如何使用转储方法将数据输出到 csv 文件?
【发布时间】:2012-06-01 05:01:56
【问题描述】:

我尝试使用 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 将设置一个实例变量,如果 字段标题以 @ 字符开头或调用 send() 传递 标头作为方法名称,字段值作为参数。这个 方法只在 Array 的第一个对象上调用。

有人知道如何将实例方法 csv_headers() 传递给这个转储函数吗?

【问题讨论】:

    标签: ruby csv


    【解决方案1】:

    我还没有对此进行测试,但看起来应该将 io 设置为文件。根据您链接的文档“io参数可用于序列化为文件”

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

    【讨论】:

    • 它可以工作,但是你知道如何将实例方法传递给那个方法吗?
    【解决方案2】:

    接受的答案并没有真正回答问题,所以我想我会举一个有用的例子。

    首先,如果您查看http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html 的文档,如果您将鼠标悬停在dump 的方法名称上,您会看到您可以click to show source。如果你这样做,你会看到dump 方法尝试在你从ary_of_objs 传入的第一个对象上调用csv_headers

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

    然后你会看到该方法会对ary_of_objs中的每个对象调用csv_dump并传入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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 2015-05-10
      • 2021-05-17
      • 2014-08-21
      • 2021-09-25
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多