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.