【问题标题】:Ruby - CSV from hash with values for each key stored verticallyRuby - 来自哈希的 CSV,其中每个键的值垂直存储
【发布时间】:2014-02-17 10:07:20
【问题描述】:

在将哈希写入 csv 时需要指针,其中键构成列名,键值是列值。

哈希的格式如下

hash = { 'A' => [ 'v', 'x', 'y' , 'z' ] , 'B' => [ 'm', 'n' , 'o' ] , 
'C' => [ 'i', 'j' , 'k' , 'l', 'm', 'n' , 'o' ] }

所需的 CSV 输出

row 0 (headers) - 'A' , 'B' , 'C'
row 1           - 'v' , 'm' , 'i'
row 2           - 'x' , 'n' , 'j'
row 3           - 'y' , 'o' , 'k'
row 4           - 'z' , ''  , 'l'
row 5           - ''  , ''  , 'm'
row 6           - ''  , ''  , 'n'
row 7           - ''  , ''  , 'o'

尝试了以下 -

csv = CSV.open ("file.csv" , 'wb', headers: true)
hash.each do |k, v|
csv[k] = v         # CSV::Table has a []= method
end

当时认为 csv[k] = v 应该可以工作,但事实并非如此。

【问题讨论】:

    标签: ruby csv hash


    【解决方案1】:

    我会这样做:

    require 'csv'
    
    output_file_path = File.expand_path('output.csv',File.dirname(__FILE__))
    
    hash = {   
               'A' => [ 'v', 'x', 'y' , 'z' ] ,
               'B' => [ 'm', 'n' , 'o' ] ,
               'C' => [ 'i', 'j' , 'k' , 'l', 'm', 'n' , 'o' ]
           }
    
    option = { 
               :headers => hash.keys,
               :write_headers => true,
               :force_quotes => true,
               :converters => CSV::Converters[:nil_to_string] = lambda do |field| 
                 field.to_s
               end
             }
    max_value_size = hash.values.map(&:size).max
    
    CSV.open(output_file_path,'w',option) do |csv|
      key_ary = hash.keys
      max_value_size.times do |index|
        csv << key_ary.map { |k| hash[k][index] } 
      end
    end
    

    输出:

    "A","B","C"
    "v","m","i"
    "x","n","j"
    "y","o","k"
    "z","","l"
    "","","m"
    "","","n"
    "","","o"
    

    【讨论】:

      【解决方案2】:
      CSV.open("/tmp/file.csv", 'wb') do |csv|
         csv << hash.keys
         max_len = hash.values.map(&:length).max
         (0...max_len).zip(*hash.values).each do |_, *row|
          csv << row
        end
      end
      

      编辑我最初使用row.compact 来匹配您的输出,但它似乎并不一致。第 4 行应该看起来像“z”,而不是“z”

      【讨论】:

      • 我刚刚编辑了这个问题。该方法在某种程度上有效,但与输出匹配有点不足。这似乎只迭代哈希中第一个键的值的数量。所以上面的第 5、6 和 7 行永远不会被写入 csv。
      • 对,我忽略了这个场景。编辑了我的答案。
      猜你喜欢
      • 2015-01-10
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-01
      相关资源
      最近更新 更多