ruby - output to csv in a similar manner 'print' outputs to terminal? -


the logic included in ruby code little difficult translate csv output, there way append each value in similar manner print works when outputting terminal?

cop_log hash of thousands of records

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 |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 

currently outputs in terminal this, want print csv in same way:

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

reading documentation looks common route following,

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

unfortunately structure of code going make little difficult....

this confusing and, if cleaned up, make code more readable , maintainable:

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 

what key? string of characters or single character? if you're matching single characters like:

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 

and convert:

elsif ('b'.. 'j').include?(key) 

to:

elsif ('b'..'j') === key 

if you're searching character match inside strings:

if key['k']   print "#{value}\n" elsif key['a']   print "#{job_number},#{pm_lookup[job_number]},#{value}," elsif key[/[b-j]/]   print "#{value}," end 

at point you're ready tackle cleaning csv output. i'd recommend starting on using 1 of the basic examples of csv output in class documentation. i'd recommend reading "comma-separated values" you're more familiar expectations of csv formatted file.

(note: @ point input sample hash added question showing actual format of keys.)

i'll let figure out how incorporate csv, meditate on this:

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) |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 

you need rely on csv class create csv files; format isn't simple seems.


here's first pass of how i'd write code:

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') |csv|   cop_log.group_by{ |k, v| k[1] }.values.each |row|     csv << [ job_number, pm_lookup[job_number], *row.map{ |k, v| v } ]   end end 

after running, foo.csv contains:

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 

we don't know expected output is, since didn't tell us, work code , figure out.

here's break-down of preprocessing of data:

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"]]] 

in code above i'm making sure input in expected order, in case i'm grouping single-digit rows. more robust code use \d+ instead of 1 , sort force appropriate order.

this important time you're massaging data 1 format later reuse. while current rubies guarantee hash maintain insertion order, it's not practice assume since old versions of ruby didn't that, , other languages port code might not maintain order. instead program defensively, making sure you're going return consistent results. extent you'll learn when find out previous attempt wasn't enough. programming fun way.

finally, time code feels awkward or isn't flowing it's time , @ you're doing.