fork download
  1. require "csv"
  2. require "pp"
  3.  
  4. data = <<END
  5. purchaser name\titem description\tprice\tcount\tmerchant address\tmerchant name
  6. Alice Bob\t$10 off $20 of food\t10.0 2\t987 Fake St\tBob's Pizza
  7. Example Name\t$30 of awesome for $10\t10.0 5\t456 Unreal Rd\tTom's Awesome Shop
  8. Name Three\t$20 Sneakers for $5\t5.0 1\t123 Fake St\tSneaker Store Emporium
  9. John Williams\t$20 Sneakers for $5\t5.0 4\t123 Fake St\tSneaker Store Emporium
  10. END
  11.  
  12. CONVERTER_SPLIT_PRICE_COUNT = lambda do |value, info|
  13. next value unless info.header == "price"
  14. price, count = value.split
  15. [ price.to_f, count.to_i ]
  16. end
  17.  
  18. def row_to_hash_fixing_price_count(row)
  19. row.headers.zip(row.fields.flatten).to_h
  20. end
  21.  
  22. csv_opts = {
  23. headers: true,
  24. col_sep: "\t",
  25. header_converters: ->(h) { h.downcase.tr(" ", "_") },
  26. converters: CONVERTER_SPLIT_PRICE_COUNT
  27. }
  28.  
  29. data_out = CSV.new(data, csv_opts).map do |row|
  30. row_to_hash_fixing_price_count(row)
  31. end
  32.  
  33. pp data_out
Success #stdin #stdout 0.08s 10840KB
stdin
Standard input is empty
stdout
[{"purchaser_name"=>"Alice Bob",
  "item_description"=>"$10 off $20 of food",
  "price"=>10.0,
  "count"=>2,
  "merchant_address"=>"987 Fake St",
  "merchant_name"=>"Bob's Pizza"},
 {"purchaser_name"=>"Example Name",
  "item_description"=>"$30 of awesome for $10",
  "price"=>10.0,
  "count"=>5,
  "merchant_address"=>"456 Unreal Rd",
  "merchant_name"=>"Tom's Awesome Shop"},
 {"purchaser_name"=>"Name Three",
  "item_description"=>"$20 Sneakers for $5",
  "price"=>5.0,
  "count"=>1,
  "merchant_address"=>"123 Fake St",
  "merchant_name"=>"Sneaker Store Emporium"},
 {"purchaser_name"=>"John Williams",
  "item_description"=>"$20 Sneakers for $5",
  "price"=>5.0,
  "count"=>4,
  "merchant_address"=>"123 Fake St",
  "merchant_name"=>"Sneaker Store Emporium "}]