Creating Hash of Arrays


#1

How can I create a hash that contains an array for its value? How can I
then
loop through the hash keys and intern the contained arrays.

Pseudo Code

myhash[‘customercode’][0]=Firstname
myhash[‘customercode’][1]=M.I
myhash[‘customercode’][2]=Lastname

myhash.each do |k,v|
myhash[‘k’].each do |elm|
puts “#{k} -> elm”
end
end


#2

myhash[‘customercode’] = Array.new

myhash[‘customercode’][0]=Firstname
myhash[‘customercode’][1]=M.I
myhash[‘customercode’][2]=Lastname

myhash.each do |el|
el.each do |elm|
puts “#{k} -> elm”
end
end

Should work. Also, if you want to have every item of the hash default
to an array, something like this to construct the Hash is what you
want:

h = Hash.new { |hash, key| hash[key] = Array.new }

Douglas


#3

Paul D. Kraus schrieb:

myhash.each do |k,v|
myhash[‘k’].each do |elm|
puts “#{k} -> elm”
end
end

ruby code:

myhash = Hash.new{|h, k| h[k] = [nil] * 3}

myhash[‘customercode’][0]=‘Firstname’
myhash[‘customercode’][1]=‘M.I’
myhash[‘customercode’][2]=‘Lastname’

myhash.each do |k,v|
myhash[k].each do |elm|
puts “#{k} -> #{elm}”
end
end

output:

customercode -> Firstname
customercode -> M.I
customercode -> Lastname

does that help?

Simon


#4

On May 22, 2006, at 4:28 PM, Paul D. Kraus wrote:

myhash.each do |k,v|
myhash[‘k’].each do |elm|
puts “#{k} -> elm”
end
end

hsh = Hash.new { |this_hash, key_that_didnt_exist| this_hash
[key_that_didnt_exist] = [] }


#5

h = Hash.new { |hash, key| hash[key] = Array.new }

Newbie here but what exactly does this like do.
Can you someone break it down for me thanks.


#6

On 5/22/06, Paul D. Kraus removed_email_address@domain.invalid wrote:

h = Hash.new { |hash, key| hash[key] = Array.new }

Newbie here but what exactly does this like do.
Can you someone break it down for me thanks.

This creates a new hash with a “default block” which will be called
whenever someone tries to get a value for a non-existent key. When the
block is called a new Array is created for the given key value and
stored in the hash. Therefore you can do things like the following and
they will just magically work:

h[:people] << “Paul”
h[:people] << “Douglas”
h[:people] << “Simon”
h[:animals] << “Dog”
h[:animals] << “Cat”
h[:animals] << “Armadillo”

Ryan


#7

2006/5/22, Paul D. Kraus removed_email_address@domain.invalid:

h = Hash.new { |hash, key| hash[key] = Array.new }

Newbie here but what exactly does this like do.
Can you someone break it down for me thanks.

From the docs: http://www.ruby-doc.org/core/classes/Hash.html#M000886

If you try and get the value using a hash key which does not exist,
then the value of the block when called with the hash and the new key
will be returned instead.

Douglas


#8

2006/5/22, Paul D. Kraus removed_email_address@domain.invalid:

How can I create a hash that contains an array for its value? How can I then
loop through the hash keys and intern the contained arrays.

Pseudo Code

myhash[‘customercode’][0]=Firstname
myhash[‘customercode’][1]=M.I
myhash[‘customercode’][2]=Lastname

Another solution picking up Daniel’s suggestion:

Item = Struct.new :first_name, :mi, :last_name
=> Item

myhash = Hash.new {|h,k| h[k]=Item.new}
=> {}

myhash[‘code’].first_name = “first”
=> “first”

myhash[‘code’].mi = “mi”
=> “mi”

myhash[‘code’].last_name = “last”
=> “last”

myhash[‘code’]
=> #<struct Item first_name=“first”, mi=“mi”, last_name=“last”>

myhash.each do |k,v|
myhash[‘k’].each do |elm|
puts “#{k} -> elm”
end
end

You’re making things more complicated than necessary. This will work
(with you array approach and with my suggestion):

myhash.each do |k, v|
?> v.each {|elm| puts “#{k} -> #{elm}” }

end
code -> first
code -> mi
code -> last
=> {“code”=>#<struct Item first_name=“first”, mi=“mi”,
last_name=“last”>}

alternative

myhash.each {|k,it| it.each {|val| print k, " -> ", val, “\n”} }
code -> first
code -> mi
code -> last
=> {“code”=>#<struct Item first_name=“first”, mi=“mi”,
last_name=“last”>}

Btw, also you use ‘k’ as a key in your iteration - you must remove the
single quotes to make it work the way you want.

Kind regards

robert