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