Forum: Ruby n00b ? re: CGI Hash and arrays

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C8c013bea094c9d799652de3fbfc0157?d=identicon&s=25 Jeff Leggett (jleggett)
on 2009-05-02 22:27
Hi, n00b here, and got myself stumped on something I thought was easy.

I get CGI params returned as:

params: {"conf_mod"=>["20"], "conf_impact"=>["10"],
"avail_impact"=>["5"], "integrity_impact"=>["5"],
"authorization"=>["5"], "integrity_mod"=>["5"]}

I just want to add up the values in the hash keys.  Seems simple, but an
hour or so later, after trying numerous things no go.  Any help
appreciated.

#!/usr/bin/ruby

require "cgi"

cgi = CGI.new('html4')
values = cgi.params
#values.each_value { |y| total += (eval y.join('+'))  }
#values.each_value { |x| total += x[0] }
#values.each_value do |v| puts v end
#cgi.header
cgi.out() do
    cgi.html() do
      cgi.head{ cgi.title{"TITLE"} } +
      cgi.body() do
        cgi.pre() do
          CGI::escapeHTML(
            "params: " + cgi.params.inspect + "\n"
           "total: " + puts(total) + "\n"
          )
        end
      end
    end
end
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2009-05-02 22:45
(Received via mailing list)
On May 2, 2009, at 4:27 PM, Jeff Leggett wrote:

> hour or so later, after trying numerous things no go.  Any help
> appreciated.

So you want to end up with total == 50, right?

The values are arrays of strings, so you need to sum up the (single)
values after turning them to integers.

total = 0
values.each_value {|v| v.each {|s| total += s.to_i } }
puts "total: #{total}"


irb> total = 0
=> 0
irb> values.each_value {|v| v.each {|s| total += s.to_i } }
=> {"conf_mod"=>["20"], "conf_impact"=>["10"], "avail_impact"=>["5"],
"integrity_impact"=>["5"], "authorization"=>["5"],
"integrity_mod"=>["5"]}
irb> puts "total: #{total}"
total: 50
=> nil

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-02 23:04
Jeff Leggett wrote:
> Hi, n00b here, and got myself stumped on something I thought was easy.
>
> I get CGI params returned as:
>
> params: {"conf_mod"=>["20"], "conf_impact"=>["10"],
> "avail_impact"=>["5"], "integrity_impact"=>["5"],
> "authorization"=>["5"], "integrity_mod"=>["5"]}
>
> I just want to add up the values in the hash keys.
>

The hash keys are the strings: "conf_mod", "conf_impact", etc.  The hash
values are the arrays.

> Seems simple, but an
> hour or so later, after trying numerous things no go.  Any help
> appreciated.
>

params = {
  "conf_mod"=>["20"],
  "conf_impact"=>["10"],
  "avail_impact"=>["5"],
  "integrity_impact"=>["5"],
  "authorization"=>["5"],
  "integrity_mod"=>["5"]
}

total = 0

params.each do |key, val|
  num_str = val[0]
  num = num_str.to_i
  total += num
end

puts total

--output:--
50
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-02 23:13
7stud -- wrote:
>
> params.each do |key, val|
>   num_str = val[0]
>   num = num_str.to_i
>   total += num
> end
>

Once you understand that, you can make it briefer:

params.each do |key, val|
  total += val[0].to_i
end

...however if it's possible that the arrays can contain more than one
string, then you need to loop over each array too.  As per Rob
Biedenharn's solution:


params = {
  "conf_mod"=>["20", "10"],
  "conf_impact"=>["10"],
  "avail_impact"=>["5", "10"],   #<--xtra strings
  "integrity_impact"=>["5"],
  "authorization"=>["5", "10"],
  "integrity_mod"=>["5"]
}

total = 0

params.each do |key, val|

  val.each do |str|
    total += str.to_i
  end

end

puts total

--output:--
80
C4316b9567c49cb866b08003ed2687d0?d=identicon&s=25 Kai D. (kaid)
on 2009-05-03 00:01
What's with inject?

params.inject(0) {|sum, (key, values)|
  sum + values.inject(0) {|a, b| a + Integer(b)}
}
This topic is locked and can not be replied to.