a newbie question~ about 2 dimension hash? really appreciate~

V

vivalon

I want to create a 2 dimension hash, and init it like
A B C D E
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0

then I can set it by ARGV
for example, if ARGV is AB2, BC5, CD7,AE6,CA2, DB3,DE8, EA3, EC9
then the expect result is
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0

well, I wrote some codes like this
#############################################
ALL="A".."E"
dimension={}
def init(dime)
tmp={}
ALL.each do |letter|
tmp[letter]=0
end
ALL.each do |letter|
dime[letter]=tmp
end
puts "Testing Init"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
end
print "Test init is over\n\n"
end
def test(array,dime)
array.each do |arr|
dime[arr[0].chr][arr[1].chr]=Integer(arr[2].chr)
end
puts "Testing"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
print "\n"
end
print "Test is over\n\n"
end

init(dimension)
test(ARGV, dimension)
#############################################
then the result will be

A B C D E
A 3 3 9 7 0
B 3 3 9 7 0
C 3 3 9 7 0
D 3 3 9 7 0
E 3 3 9 7 0

please tell me why i am wrong?
I thought the "last" decide the whole volume
like EC9 make C volume 9
EA3 make A volume 3
please help me~
thank you so much~
 
R

Robert Dober

I want to create a 2 dimension hash, and init it like
A B C D E
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0

then I can set it by ARGV
for example, if ARGV is AB2, BC5, CD7,AE6,CA2, DB3,DE8, EA3, EC9
then the expect result is
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0

well, I wrote some codes like this
#############################################
ALL="A".."E"
dimension={}
def init(dime)
tmp={}
ALL.each do |letter|
tmp[letter]=0
end
ALL.each do |letter|
dime[letter]=tmp
end
puts "Testing Init"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
end
print "Test init is over\n\n"
end
def test(array,dime)
array.each do |arr|
dime[arr[0].chr][arr[1].chr]=Integer(arr[2].chr)
end
puts "Testing"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
print "\n"
end
print "Test is over\n\n"
end

init(dimension)
test(ARGV, dimension)
#############################################
then the result will be

A B C D E
A 3 3 9 7 0
B 3 3 9 7 0
C 3 3 9 7 0
D 3 3 9 7 0
E 3 3 9 7 0

please tell me why i am wrong?
I thought the "last" decide the whole volume
like EC9 make C volume 9
EA3 make A volume 3
please help me~
thank you so much~
Sorry for not having more time right now but the pattern recalls shared objects
when you do this

c> dime[letter]=tmp

in init you share all lines and they will always refer to the same object.

try this and tell me if that solves your issue

c> dime[letter]=tmp.dup

HTH
Robert
 
R

Robert Klemme

2007/10/4 said:
I want to create a 2 dimension hash, and init it like
A B C D E
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0

then I can set it by ARGV
for example, if ARGV is AB2, BC5, CD7,AE6,CA2, DB3,DE8, EA3, EC9
then the expect result is
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0

well, I wrote some codes like this
#############################################
ALL="A".."E"
dimension={}
def init(dime)
tmp={}
ALL.each do |letter|
tmp[letter]=0
end
ALL.each do |letter|
dime[letter]=tmp
end
puts "Testing Init"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
end
print "Test init is over\n\n"
end
def test(array,dime)
array.each do |arr|
dime[arr[0].chr][arr[1].chr]=Integer(arr[2].chr)
end
puts "Testing"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
print "\n"
end
print "Test is over\n\n"
end

init(dimension)
test(ARGV, dimension)
#############################################
then the result will be

A B C D E
A 3 3 9 7 0
B 3 3 9 7 0
C 3 3 9 7 0
D 3 3 9 7 0
E 3 3 9 7 0

please tell me why i am wrong?
I thought the "last" decide the whole volume
like EC9 make C volume 9
EA3 make A volume 3
please help me~
thank you so much~
Sorry for not having more time right now but the pattern recalls shared objects
when you do this

c> dime[letter]=tmp

in init you share all lines and they will always refer to the same object.

try this and tell me if that solves your issue

c> dime[letter]=tmp.dup

HTH
Robert

I guess you are right with regard to the aliasing effect.

Here's another solution:

RKlemme@padrklemme1 /cygdrive/c/SCMws/RKlemme
$ cat ~/ruby/matrix.rb
#!ruby
ALL="A".."E"
args = %w{AB2 BC5 CD7 AE6 CA2 DB3 DE8 EA3 EC9}
matrix = Hash.new 0
args.each do |a|
d1, d2, v = a.scan /./
matrix[[d1, d2]] = v.to_i
end

print " ", ALL.to_a.join(" "), "\n"
ALL.each do |d1|
print d1
ALL.each do |d2|
print " ", matrix[[d1,d2]]
end
print "\n"
end

require 'pp'
pp matrix

RKlemme@padrklemme1 /cygdrive/c/SCMws/RKlemme
$ ~/ruby/matrix.rb
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0
{["A", "E"]=>6,
["A", "B"]=>2,
["D", "B"]=>3,
["C", "A"]=>2,
["E", "C"]=>9,
["D", "E"]=>8,
["C", "D"]=>7,
["E", "A"]=>3,
["B", "C"]=>5}

Kind regards

robert
 
V

vivalon

I want to create a 2 dimension hash, and init it like
A B C D E
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0
then I can set it by ARGV
for example, if ARGV is AB2, BC5, CD7,AE6,CA2, DB3,DE8, EA3, EC9
then the expect result is
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0
well, I wrote some codes like this
#############################################
ALL="A".."E"
dimension={}
def init(dime)
tmp={}
ALL.each do |letter|
tmp[letter]=0
end
ALL.each do |letter|
dime[letter]=tmp
end
puts "Testing Init"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
end
print "Test init is over\n\n"
end
def test(array,dime)
array.each do |arr|
dime[arr[0].chr][arr[1].chr]=Integer(arr[2].chr)
end
puts "Testing"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
print "\n"
end
print "Test is over\n\n"
end
init(dimension)
test(ARGV, dimension)
#############################################
then the result will be
A B C D E
A 3 3 9 7 0
B 3 3 9 7 0
C 3 3 9 7 0
D 3 3 9 7 0
E 3 3 9 7 0
please tell me why i am wrong?
I thought the "last" decide the whole volume
like EC9 make C volume 9
EA3 make A volume 3
please help me~
thank you so much~

Sorry for not having more time right now but the pattern recalls shared objects
when you do this

c> dime[letter]=tmp

in init you share all lines and they will always refer to the same object.

try this and tell me if that solves your issue

c> dime[letter]=tmp.dup

HTH
Robert

that's really helpful~
thank you very much ^O^
 
V

vivalon

2007/10/4, Robert Dober <[email protected]>:


I want to create a 2 dimension hash, and init it like
A B C D E
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0
then I can set it by ARGV
for example, if ARGV is AB2, BC5, CD7,AE6,CA2, DB3,DE8, EA3, EC9
then the expect result is
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0
well, I wrote some codes like this
#############################################
ALL="A".."E"
dimension={}
def init(dime)
tmp={}
ALL.each do |letter|
tmp[letter]=0
end
ALL.each do |letter|
dime[letter]=tmp
end
puts "Testing Init"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
end
print "Test init is over\n\n"
end
def test(array,dime)
array.each do |arr|
dime[arr[0].chr][arr[1].chr]=Integer(arr[2].chr)
end
puts "Testing"
ALL.each do |key1|
ALL.each do |key2|
print key1+key2+" value="
puts dime[key1][key2]
end
print "\n"
end
print "Test is over\n\n"
end
init(dimension)
test(ARGV, dimension)
#############################################
then the result will be
A B C D E
A 3 3 9 7 0
B 3 3 9 7 0
C 3 3 9 7 0
D 3 3 9 7 0
E 3 3 9 7 0
please tell me why i am wrong?
I thought the "last" decide the whole volume
like EC9 make C volume 9
EA3 make A volume 3
please help me~
thank you so much~
Sorry for not having more time right now but the pattern recalls shared objects
when you do this
c> dime[letter]=tmp
in init you share all lines and they will always refer to the same object.
try this and tell me if that solves your issue
c> dime[letter]=tmp.dup
HTH
Robert

I guess you are right with regard to the aliasing effect.

Here's another solution:

RKlemme@padrklemme1 /cygdrive/c/SCMws/RKlemme
$ cat ~/ruby/matrix.rb
#!ruby
ALL="A".."E"
args = %w{AB2 BC5 CD7 AE6 CA2 DB3 DE8 EA3 EC9}
matrix = Hash.new 0
args.each do |a|
d1, d2, v = a.scan /./
matrix[[d1, d2]] = v.to_i
end

print " ", ALL.to_a.join(" "), "\n"
ALL.each do |d1|
print d1
ALL.each do |d2|
print " ", matrix[[d1,d2]]
end
print "\n"
end

require 'pp'
pp matrix

RKlemme@padrklemme1 /cygdrive/c/SCMws/RKlemme
$ ~/ruby/matrix.rb
A B C D E
A 0 2 0 0 6
B 0 0 5 0 0
C 2 0 0 7 0
D 0 3 0 0 8
E 3 0 9 0 0
{["A", "E"]=>6,
["A", "B"]=>2,
["D", "B"]=>3,
["C", "A"]=>2,
["E", "C"]=>9,
["D", "E"]=>8,
["C", "D"]=>7,
["E", "A"]=>3,
["B", "C"]=>5}

Kind regards

robert

thank you very much for helping me ^O^
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top