Smooth
Smooth

Reputation: 956

Reading text file, parsing it, and storing it into a hash. How?

I want to open a text file with three lines

3 televisions at 722.49

1 carton of eggs at 14.99

2 pairs of shoes at 34.85

and turn it into this:

hash = {
      "1"=>{:item=>"televisions", :price=>722.49, :quantity=>3},    
      "2"=>{:item=>"carton of eggs", :price=>14.99, :quantity=>1},
      "3"=>{:item=>"pair of shoes", :price=>34.85, :quantity=>2}
       }

I'm very stuck not sure how to go about doing this. Here's what I have so far:

f = File.open("order.txt", "r")
lines = f.readlines
h = {}
n = 1
while n < lines.size
lines.each do |line|
  h["#{n}"] = {:quantity => line[line =~ /^[0-9]/]}
  n+=1
end
end

Upvotes: 2

Views: 5664

Answers (4)

glenn mcdonald
glenn mcdonald

Reputation: 15488

No reason for anything this simple to look ugly!

h = {}
lines.each_with_index do |line, i|
  quantity, item, price = line.match(/^(\d+) (.*) at (\d+\.\d+)$/).captures
  h[i+1] = {quantity: quantity.to_i, item: item, price: price.to_f}
end

Upvotes: 9

abathur
abathur

Reputation: 1047

I don't know ruby so feel free to ignore my answer as I'm just making assumptions based on documentation, but I figured I'd provide a non-regex solution since it seems like overkill in a case like this.

I'd assume you can just use line.split(" ") and assign position [0] to quantity, position [-1] to price, and then assign item to [1..-3].join(" ")

Per the first ruby console I could find:

test = "3 telev­isions at 722.4­9"
foo = test.­split(" ")
hash = {1=>{:item=>foo[1..-3]­.join(" "),:q­uantity=>foo[0], :price=>foo[-1]}}

=> {1=>{:item=>"televisions", :quantity=>"3", :price=>"722.49"}}

Upvotes: 0

Victor Deryagin
Victor Deryagin

Reputation: 12225

hash = File.readlines('/path/to/your/file.txt').each_with_index.with_object({}) do |(line, idx), h|
  /(?<quantity>\d+)\s(?<item>.*)\sat\s(?<price>\d+(:?\.\d+)$)/ =~ line
  h[(idx + 1).to_s] = {:item => item, :price => price.to_f, :quantity => quantity.to_i}
end

Upvotes: 1

halfelf
halfelf

Reputation: 10107

File.open("order.txt", "r") do |f|
  n,h = 0,{}
  f.each_line do |line|
    n += 1
    line =~ /(\d) (.*) at (\d*\.\d*)/
    h[n.to_s] = { :quantity => $1.to_i, :item => $2, :price => $3 }
  end
end

Upvotes: 1

Related Questions