Hashed matrix

Y

Yoann Moreau

Hello, I'd like to use a specific matrix with string as key for lines
and integer index for columns. I could also use string for columns (a
string version of integer), it doesn't matter. I use the matrix to store
a small object (named State) I just need to access data like that :
matrix[a_string][a_number]

Here is how I tried to do it :
matrix = Hash.new{ |hash, key| hash[key] = Array.new(5, State.new(0,
"")) }

But I have strange values, is there a better way to make that matrix ?
 
R

Robert Klemme

2009/4/20 Yoann Moreau said:
Hello, I'd like to use a specific matrix with string as key for lines
and integer index for columns. I could also use string for columns (a
string version of integer), it doesn't matter. I use the matrix to store
a small object (named State) I just need to access data like that :
matrix[a_string][a_number]

Here is how I tried to do it :
matrix = Hash.new{ |hash, key| hash[key] = Array.new(5, State.new(0,
"")) }

You want the block form of Array.new because otherwise all array
entries point to the same object:

matrix = Hash.new{ |hash, key| hash[key] = Array.new(5) { State.new(0,"") } }

Alternative approach: use an Array of String and Fixnum as Hash key:

class Matrix
def initialize
@hash = Hash.new {|h,k| h[k] = State.new(0, "")}
end

def [](row,col)
@hash[[row, col]]
end

def []=(row,col, val)
raise ArgumentError, "Not a state %p" % val
@hash[[row, col]] = val
end
end

This is likely more efficient if your matrices are large and sparse.

Kind regards

robert
 
R

Robert Klemme

2009/4/20 Robert Klemme said:
2009/4/20 Yoann Moreau said:
Hello, I'd like to use a specific matrix with string as key for lines
and integer index for columns. I could also use string for columns (a
string version of integer), it doesn't matter. I use the matrix to store
a small object (named State) I just need to access data like that :
matrix[a_string][a_number]

Here is how I tried to do it :
matrix =3D Hash.new{ |hash, key| hash[key] =3D Array.new(5, State.new(0,
"")) }

You want the block form of Array.new because otherwise all array
entries point to the same object:

matrix =3D Hash.new{ |hash, key| hash[key] =3D Array.new(5) { State.new(0= ,"") } }

Alternative approach: use an Array of String and Fixnum as Hash key:

class Matrix
=A0def initialize
=A0 =A0@hash =3D Hash.new {|h,k| h[k] =3D State.new(0, "")}
=A0end

=A0def [](row,col)
=A0 =A0@hash[[row, col]]
=A0end

=A0def []=3D(row,col, val)
=A0 =A0raise ArgumentError, "Not a state %p" % val

This should have read

raise ArgumentError, "Not a state %p" % val unless State =3D=3D=3D val
=A0 =A0@hash[[row, col]] =3D val
=A0end
end

This is likely more efficient if your matrices are large and sparse.

Kind regards

robert



--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Y

Yoann Moreau

Thanks for your answer, you're right I had the same object in my array,
this is why I had strange values.
I use a really small matrix so it's not a big deal to be efficient, I'll
use your first idea.

Thank you.
 

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,774
Messages
2,569,596
Members
45,142
Latest member
DewittMill
Top