require "csv" require "pp" data = <<END purchaser name\titem description\tprice\tcount\tmerchant address\tmerchant name Alice Bob\t$10 off $20 of food\t10.0 2\t987 Fake St\tBob's Pizza Example Name\t$30 of awesome for $10\t10.0 5\t456 Unreal Rd\tTom's Awesome Shop Name Three\t$20 Sneakers for $5\t5.0 1\t123 Fake St\tSneaker Store Emporium John Williams\t$20 Sneakers for $5\t5.0 4\t123 Fake St\tSneaker Store Emporium END CONVERTER_SPLIT_PRICE_COUNT = lambda do |value, info| next value unless info.header == "price" price, count = value.split [ price.to_f, count.to_i ] end def row_to_hash_fixing_price_count(row) row.headers.zip(row.fields.flatten).to_h end csv_opts = { headers: true, col_sep: "\t", header_converters: ->(h) { h.downcase.tr(" ", "_") }, converters: CONVERTER_SPLIT_PRICE_COUNT } data_out = CSV.new(data, csv_opts).map do |row| row_to_hash_fixing_price_count(row) end pp data_out
Standard input is empty
[{"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 "}]