2013-03-09 91 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