Dan Tappin
Dan Tappin

Reputation: 3032

Summing values from a hash

I have a model where I am am storing some related data in a hash like this:

line_items_attributes"=>[{"major"=>"8762", "minor"=>"322", "description"=>"Engineering", "amount"=>"200000", "active"=>"1"}, {"major"=>"8762", "minor"=>"445", "description"=>"Tanks", "amount"=>"2100000", "active"=>"1"}, {"major"=>"8762", "minor"=>"500", "description"=>"Pipe, Valves & Fittings", "amount"=>"150000", "active"=>"1"}]

I went this way to avoid another related model etc.

I amy playing with this prototype from this website:

http://daniel.fone.net.nz/blog/2013/10/19/prototyping-web-applications-in-rails-4/?utm_source=rubyweekly&utm_medium=email

Anyway I want to all the 'amount' values. I have Googled a few solutions but I don't know enough about hashes to figure this out.

I tried:

2.0.0-p247 :053 > line_items_attributes.inject(0) {|sum, hash| sum + hash["amount"]}
TypeError: no implicit conversion of String into Integer
    from (irb):53:in `[]'
    from (irb):53:in `block in irb_binding'
    from (irb):53:in `each'
    from (irb):53:in `inject'
    from (irb):53
    from /Users/dan/.rvm/gems/ruby-2.0.0-p247@global/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from /Users/dan/.rvm/gems/ruby-2.0.0-p247@global/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/dan/.rvm/gems/ruby-2.0.0-p247@global/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

I even tried adding hash["amount"].to_i but that didn't work. I think I am close but sure I am missing something obvious to someone more experienced.

On a side note I have seen other hash notations show such as:

line_items_attributes"=>[{major:"8762", minor:"322" etc. is there an advantage to this?

Upvotes: 0

Views: 83

Answers (2)

Dan Tappin
Dan Tappin

Reputation: 3032

D'oh! After looking again I missed the fact that the data being stored was actually:

{"line_items_attributes"=>[{"major"=>"8762", "minor"=>"322", "description"=>"Engineering", "amount"=>"200000", "active"=>"1"}, {"major"=>"8762", "minor"=>"445", "description"=>"Tanks", "amount"=>"2100000", "active"=>"1"}, {"major"=>"8762", "minor"=>"500", "description"=>"Pipe, Valves & Fittings", "amount"=>"150000", "active"=>"1"}]}

So now I ran this:

Model.find(1).data["line_items_attributes"].inject(0) {|sum, hash| sum + hash["amount"].to_i}

and all is good. I probably don't need to store it that way but I was just using that prototype tutorial as an example.

Thanks to those who took the time to look at this. I had figured it out on my own... sort of.

Upvotes: 0

CDub
CDub

Reputation: 13354

This works for me:

2.0.0p247 :028 > line_items_attributes = [{"major"=>"8762", "minor"=>"322", "description"=>"Engineering", "amount"=>"200000", "active"=>"1"}, {"major"=>"8762", "minor"=>"445", "description"=>"Tanks", "amount"=>"2100000", "active"=>"1"}, {"major"=>"8762", "minor"=>"500", "description"=>"Pipe, Valves & Fittings", "amount"=>"150000", "active"=>"1"}]
 => [{"major"=>"8762", "minor"=>"322", "description"=>"Engineering", "amount"=>"200000", "active"=>"1"}, {"major"=>"8762", "minor"=>"445", "description"=>"Tanks", "amount"=>"2100000", "active"=>"1"}, {"major"=>"8762", "minor"=>"500", "description"=>"Pipe, Valves & Fittings", "amount"=>"150000", "active"=>"1"}] 

2.0.0p247 :036 > line_items_attributes.inject(0) {|sum, hash| sum += hash["amount"].to_i; sum}
 => 2450000 

Upvotes: 1

Related Questions