Hash .each and different action for each key

Hello -
I have a hash table of several items.

What I would like to do is loop through the hash and do a different
action based on each unique key.

my_hash_table.each_pair do |k, v|

Call a method if a hash key == “a”

Call a different method if hash key == “b”

Call a third method if a hash key == “c”

end

I have been trying to implement this with “if” and “case”, but the loop
stops once the first argument is satisfied.

Can you please point into the right direction of how to go about solving
this problem.

Thank you!

Igor Nn wrote in post #1001604:

What I would like to do is loop through the hash and do a different
action based on each unique key.

my_hash_table.each_pair do |k, v|

Call a method if a hash key == “a”

Call a different method if hash key == “b”

Call a third method if a hash key == “c”

end

I have been trying to implement this with “if” and “case”, but the loop
stops once the first argument is satisfied.

Then show your code. “if” and “case” will be able to do this just fine.

Make a small standalone test program, e.g. start it with

my_hash_table = {“a”=>42, “b”=>999, “c”=>123}

Then when you post it here, we will be able to run it too and duplicate
your problem.

On Sat, 28 May 2011 04:44:20 +0900
Igor Nn [email protected] wrote:

Hello -
I have a hash table of several items.

What I would like to do is loop through the hash and do a different
action based on each unique key.

my_hash_table.each_pair do |k, v|

Call a method if a hash key == “a”

Call a different method if hash key == “b”

Call a third method if a hash key == “c”

end

What you ask for is this:

funcs = {}
funcs[“a”] == lambda {|v| puts “method for key ‘a’ with value: #{v}”}

my_hash_table = {}
my_hash_table[“a”] = “Hmmmmm!”

my_hash_table.each_pair do |k, v|
funcs[k].call v
end

Are you sure you want that? It smells way bad. It’s incoherent.

Is there any thing wrong with the hash values being objects which do
what you want, in each case.

E.g.

class Car
def drive
puts “broom, broom!”
end
end

class Moped
def drive
puts “nnnnnnnnn!”
end
end

vehicles = {}
vehicles[“a”] = Car.new
vehicles[“b”] = Moped.new

vehicles.each_value do |veh|
veh.drive
end

Much more coherant. Abstracts detail of algorithm from loop body into
objects in well defined manner. Can be extended to do different things.

Cheers
Johnny

def one(x)
puts “1. #{x}”
end
def two(x)
puts “2. #{x}”
end
def three(x)
puts “3. #{x}”
end

my_hash_table = {“a”=>42, “b”=>999, “c”=>123}

my_hash_table.each_pair do |k, v|
if k == “a”
one(v)
end
if k == “b”
two(v)
end
if k == “c”
three(v)
end
end

Leigh D. wrote in post #1001612:

if k == “a”
one(v)
end
if k == “b”
two(v)
end
if k == “c”
three(v)
end
end

That is an inefficient construct: three if tests must be
exectued for every key–no matter what. Compare that to:

if k == ‘a’

elsif k == ‘b’

elsif k == ‘c’

else

A ‘when statement’ works similarly.

Thank you for the response.

I was able to get the following to work after reading up more on the
case statement (Was omitting the “when” :slight_smile:

def test_case(choices)
choices.each_pair do |k, v|
case k
when :a
puts “This is a”
when :b
puts “This is b”
when :c
puts “This is c”
end
end
end

Thank you for your help.

myhashtable= {:a => ‘foo’, :b => ‘moo’}

myhashtable.each {|k, v| actions[k].call(v)}

That’s what I proposed but it’s a bit daft no? I mean, you’re
associating a function with each key, there are already constructs
which do this!

What’s wrong with an Array of objects? It has the same semantics, in
this limited case, and is 100 times less weird.

I have a hash table of several items.

What I would like to do is loop through the hash and do a different
action based on each unique key.
[…]
Can you please point into the right direction of how to go about solving
this problem.

Maybe you can adapt the following pattern to your needs:

actions = {
:a => lambda{|*args| puts “action ‘a’ called with #{args}” },
:b => lambda{|*args| puts “action ‘b’ called with #{args}” }
}

myhashtable= {:a => ‘foo’, :b => ‘moo’}

myhashtable.each {|k, v| actions[k].call(v)}

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs