2013-03-09 75 views
0

我有以下哈希名为fcs,并希望将其保存为CSV。将哈希转换为csv文件

{ 
    "bla"=>{ 
      "lower"=>[17.12241, 18.79847, 17.71413, 18.49174, 18.30381, 18.78557, 18.93176, 19.33453, 19.62619, 20.02301], 
      "point"=>[21.84838, 23.86319, 23.93176, 25.19658, 25.72613, 26.70761, 27.41132, 28.28576, 29.05525, 29.88925], 
      "upper"=>[26.57434, 28.92791, 30.14938, 31.90142, 33.14845, 34.62966, 35.89088, 37.23698, 38.48432, 39.7555] 
     }, 
    "blo"=>{ 
      "lower"=>[17.12241, 18.79847, 17.71413, 18.49174, 18.30381, 18.78557, 18.93176, 19.33453, 19.62619, 20.02301], 
      "point"=>[21.84838, 23.86319, 23.93176, 25.19658, 25.72613, 26.70761, 27.41132, 28.28576, 29.05525, 29.88925], 
      "upper"=>[26.57434, 28.92791, 30.14938, 31.90142, 33.14845, 34.62966, 35.89088, 37.23698, 38.48432, 39.7555] 
     } 
} 

这是输出文件的所需内容:

lower.bla,bla,upper.bla,lower.blo,blo,upper.blo 
17.12241,21.84838,26.57434,17.12241,21.84838,26.57434 
18.79847,23.86319,28.92791,18.79847,23.86319,28.92791 
. 
. 
. 

我使用下面的代码来生成它:

def to_csv 
    fcs = self.fcs 
    CSV.generate(col_sep: self.delim) do |csv| 
    names = Array.new 
    cols = Array.new 
    fcs.keys.each do |ts| 
     names << "lower." + ts 
     names << ts 
     names << "upper." + ts 
    end 
    csv << names 
    fcs.values.each do |ts| 
     cols << ts.values  
    end 
    cols.flatten(1).transpose.each do |row| 
     csv << row 
    end 
    end 
end 

但是它使用三种不同的循环。我感觉这不是实现所需输出的最佳代码。有没有最好的方法来重写它?

回答

1
header, body = 
fcs 
.flat_map{|k1, h| h.map{|k2, v| ["#{k2}.#{k1}".sub(/point\./, ""), v]}} 
.transpose 

[header, *body.transpose].map{|e| e.join(",")}.join($/) 

给出:

lower.bla,bla,upper.bla,lower.blo,blo,upper.blo 
17.12241,21.84838,26.57434,17.12241,21.84838,26.57434 
18.79847,23.86319,28.92791,18.79847,23.86319,28.92791 
17.71413,23.93176,30.14938,17.71413,23.93176,30.14938 
18.49174,25.19658,31.90142,18.49174,25.19658,31.90142 
18.30381,25.72613,33.14845,18.30381,25.72613,33.14845 
18.78557,26.70761,34.62966,18.78557,26.70761,34.62966 
18.93176,27.41132,35.89088,18.93176,27.41132,35.89088 
19.33453,28.28576,37.23698,19.33453,28.28576,37.23698 
19.62619,29.05525,38.48432,19.62619,29.05525,38.48432 
20.02301,29.88925,39.7555,20.02301,29.88925,39.7555 
+0

要命!我需要学习如何获得最多的地图功能! – 2013-03-09 23:48:51

+0

虽然在数值上使用'join(',')'工作,但对字符串不是个好主意。 CSV是一种标准,处理嵌入逗号和引用字符串的方法可能会变得非常复杂,比单个'join'可以处理的要多得多。 CSV模块为我们处理这种复杂性,所以依赖于它,除非像这样非常简单的用法。 – 2013-03-10 05:06:34

+0

我知道。我只是回答了提供的数据就像问题中的内容。 – sawa 2013-03-10 13:42:14