Hash .each and different action for each key

I

Igor Nn

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!
 
B

Brian Candler

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.
 
J

Johnny Morrice

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
 
L

Leigh Daniels

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

my=5Fhash=5Ftable =3D {"a"=3D>42, "b"=3D>999, "c"=3D>123}

my=5Fhash=5Ftable.each=5Fpair do |k, v|
if k =3D=3D "a"
one(v)
end
if k =3D=3D "b"
two(v)
end
if k =3D=3D "c"
three(v)
end
end
 
I

Igor Nn

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" :)

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.
 
7

7stud --

Leigh Daniels 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 a horribly 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.
 
A

Anurag Priyam

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)}
 
J

Johnny Morrice

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top