2016-06-06 55 views
-1

我的紅寶石代碼中包含的邏輯有點難以轉化爲csv輸出,有沒有辦法以類似的方式追加每個valueprint在輸出到終端時工作?以類似的方式輸出到csv'打印'輸出到終端?

cop_log是幾千條記錄的哈希

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4, 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10, 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15, 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21, 'K2' => 'val22'} 

cop_log.each do |key, value| 
    if key.include?('K') 
    print "#{value}\n" 
    elsif key.include?('A') 
    print "#{job_number},#{pm_lookup[job_number]},#{value}," 
    elsif key.include?('B') || key.include?('C') || key.include?('D') || 
     key.include?('E') || key.include?('F') || key.include?('G') || 
     key.include?('H') || key.include?('I') || key.include?('J') 
    print "#{value}," 
    end 
end 

目前輸出在這樣的終端,我希望它打印到CSV以同樣的方式:

val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11 
val12, val13, val14, val15, val16, val17, val18, val19, val10, val21, val22 

閱讀文檔它看起來像常見的路線是做以下事情,

CSV.open("path/to/file.csv", "wb") do |csv| 
    csv << ["row", "of", "CSV", "data"] 
    csv << ["another", "row"] 
    # ... 
end 

不幸的是s我的代碼結構會使這有點困難....

+1

當我們正在學習,我們傾向於自己畫成角落,試圖通過想改變的API,而不是我們的代碼擺脫的局面的API。按照流程來使用API​​並更好地使用API​​。你會發現你的代碼會更具可讀性。正如所寫的,你的代碼不是慣用的,可以更清晰地重寫。我認爲這是一個重構的機會。至於你的「問題」,你沒有問過。我們可以猜測你需要幫助,但如果你更清楚地陳述你的目標,它會幫助我們和其他人。 –

+0

你的鑰匙是什麼樣的?他們是單字母,還是你想要在字符串中查找字母?請閱讀「[問]」和「[mcve]」。我們需要最少的輸入數據和預期的輸出。 –

+0

感謝您的意見和回答,關鍵是從excel電子表格中使用溪谷寶石編譯出來的散列。一個完整的excel電子表格在我的散列內,散列鍵是A1,B1,C1,A2,B2,C2等每個單元格。我的代碼正在排列每一行。其用於與特定公司使用的特定Excel文件模板一起工作。我會重新考慮我的方法。 @theTinMan – aronlmin

回答

0

你不能這樣做嗎?

CSV.open("path/to/file.csv", "wb") do |csv| 
    cop_log.each do |key, value| 
     if key.include?('A') 
      csv << [ job_number, pm_lookup[job_number], value ] 
     elsif key.include?('K') || key.include?('B') || key.include?('C') || key.include?('D') || 
      key.include?('E') || key.include?('F') || key.include?('G') || 
      key.include?('H') || key.include?('I') || key.include?('J') 
      csv << [ value ] 
     end 
    end 
end 
0
def write_csv(cop_log, io = $stdout) 
    cop_log.each do |key, value| 
    if key.include?('K') 
     io.print "#{value}\n" 
    elsif key.include?('A') 
     io.print "#{job_number},#{pm_lookup[job_number]},#{value}," 
    elsif key.include?('B') || key.include?('C') || key.include?('D') || 
      key.include?('E') || key.include?('F') || key.include?('G') || 
      key.include?('H') || key.include?('I') || key.include?('J') 
     io.print "#{value}," 
    end 
    end 
end 

然後

File.open('path/to/file.csv', 'w') do |f| 
    write_csv(cop_log, f) 
end 
1

這是非常混亂,如果清理,將有助於使你的代碼更具可讀性和可維護性:

if key.include?('K') 
    print "#{value}\n" 
elsif key.include?('A') 
    print "#{job_number},#{pm_lookup[job_number]},#{value}," 
elsif key.include?('B') || key.include?('C') || key.include?('D') || 
    key.include?('E') || key.include?('F') || key.include?('G') || 
    key.include?('H') || key.include?('I') || key.include?('J') 
    print "#{value}," 
end 

什麼是key?一串字符或單個字符?如果你匹配單個字符,你可以這樣做:

if key == 'K' 
    print "#{value}\n" 
elsif key == 'A' 
    print "#{job_number},#{pm_lookup[job_number]},#{value}," 
elsif ('B'.. 'J').include?(key) 
elsif 
    print "#{value}," 
end 

,甚至轉換:

elsif ('B'.. 'J').include?(key) 

到:

elsif ('B'..'J') === key 

如果你在裏面尋找一個字符匹配字符串:

if key['K'] 
    print "#{value}\n" 
elsif key['A'] 
    print "#{job_number},#{pm_lookup[job_number]},#{value}," 
elsif key[/[B-J]/] 
    print "#{value}," 
end 

此時您已準備好解決清理CSV輸出的問題。我建議重新開始在類文檔中使用CSV輸出的the basic examples之一。我還建議您仔細閱讀「Comma-separated values」,以便您更熟悉CSV格式文件的期望。

(注:此時加入顯示按鍵的實際格式問題的輸入採樣哈希值。)

我會讓你想出如何把CSV,但默想這一點:

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4', 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10', 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15', 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21', 'K2' => 'val22'} 
cop_log.values.each_slice(11) do |slice| 
    puts slice.join(',') 
end 

# >> val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11 
# >> val12,val13,val14,val15,val16,val17,val18,val19,val20,val21,val22 

您需要依靠CSV類創建CSV文件;格式並不像看起來那麼簡單。


下面是我怎麼會寫代碼第一遍:

require 'csv' 

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4', 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10', 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15', 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21', 'K2' => 'val22'} 

job_number = 1 
pm_lookup = [0, 1] 

CSV.open('./foo.csv', 'w') do |csv| 
    cop_log.group_by{ |k, v| k[1] }.values.each do |row| 
    csv << [ job_number, pm_lookup[job_number], *row.map{ |k, v| v } ] 
    end 
end 

運行後,foo.csv包含:

1,1,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11 
1,1,val12,val13,val14,val15,val16,val17,val18,val19,val20,val21,val22 

我們不知道你的預期成果是什麼,因爲你沒有告訴我們,但是你可以從那個代碼開始工作並找出答案。

這裏的數據的預處理的擊穿:

cop_log.group_by{ |k, v| k[1] } # => {"1"=>[["A1", "val1"], ["B1", "val2"], ["C1", "val3"], ["D1", "val4"], ["E1", "val5"], ["F1", "val6"], ["G1", "val7"], ["H1", "val8"], ["I1", "val9"], ["J1", "val10"], ["K1", "val11"]], "2"=>[["A2", "val12"], ["B2", "val13"], ["C2", "val14"], ["D2", "val15"], ["E2", "val16"], ["F2", "val17"], ["G2", "val18"], ["H2", "val19"], ["I2", "val20"], ["J2", "val21"], ["K2", "val22"]]} 
     .values # => [[["A1", "val1"], ["B1", "val2"], ["C1", "val3"], ["D1", "val4"], ["E1", "val5"], ["F1", "val6"], ["G1", "val7"], ["H1", "val8"], ["I1", "val9"], ["J1", "val10"], ["K1", "val11"]], [["A2", "val12"], ["B2", "val13"], ["C2", "val14"], ["D2", "val15"], ["E2", "val16"], ["F2", "val17"], ["G2", "val18"], ["H2", "val19"], ["I2", "val20"], ["J2", "val21"], ["K2", "val22"]]] 

在上面的代碼,我要確保輸入的是在預期的順序,在這種情況下,我通過單分組數字行。更可靠的代碼將使用\d+而不是1,並且還將排序以強制執行相應的順序。

每當您將數據從一種格式轉換爲另一種格式以供日後重複使用時,這非常重要。儘管目前的Rubies可以保證散列可以維持其插入順序,但假設由於舊版本的Ruby沒有這樣做並不是一種好的做法,而且您移植代碼的其他語言可能無法維護順序。相反,總是在防守方面進行編程,確保你將返回一致的結果。當你發現以前的嘗試是不夠的時候,你會在多大程度上學到這些東西。編程很有趣。最後,任何時候你的代碼感到尷尬或者不流淌,都需要時間來備份,看看你在做什麼。

+0

不幸的是,每個關鍵字都是一個字母數字對,它直接來自excel電子表格,A1,B1,C1,A2,B2,C2等,感謝您的回覆,儘管 – aronlmin

+0

我添加了代碼,顯示了我會如何去做。 –

0

重新fector代碼

CSV.open("test.csv", "ab") do |csv| 
     b = {} 
     check_num = 0 
     cop_log.each do |key, value| 
     num = key.gsub(/[^\d]/, '').to_i 
     next if num < 8 || 
       key.include?('L') || key.include?('M') || key.include?('N') || 
       key.include?('O') || key.include?('P') || key.include?('Q') || 
       key.include?('R') || key.include?('S') || key.include?('T') || 
       key.include?('U') || key.include?('V') 
     a = { key => value } 
     b.merge!(a) 
     end # end of each loop 
     i = 8 
     while ((b.length/9) - 7) > i do 
     csv << [ job_number, pm_lookup[job_number], b["A#{i}"], b["B#{i}"], 
       b["C#{i}"], b["D#{i}"], b["E#{i}"], b["F#{i}"], b["G#{i}"], 
       b["H#{i}"], b["I#{i}"], b["J#{i}"], b["K#{i}"] ] 
     i += 1 
     end 
    end # end of CSV.open