how to create a hash whose key is a reference

F

freesoft12

Hi,

I am creating 2 hash tables. In the first hash table I have a string
as the key but in the second one I want the reference to that string
as the key, to save memory.
ie.
$hash_table_one[$string_key]
^
|
$hash_table_two[$string_key_ref] -> this key is a reference to the
first table's key

Regards
John
 
G

Gunnar Hjalmarsson

I am creating 2 hash tables. In the first hash table I have a string
as the key but in the second one I want the reference to that string
as the key,

Not possible. Hash keys are always strings.
 
J

Jürgen Exner

I am creating 2 hash tables. In the first hash table I have a string
as the key but in the second one I want the reference to that string
as the key, to save memory.
ie.
$hash_table_one[$string_key]
^
|
$hash_table_two[$string_key_ref] -> this key is a reference to the
first table's key

You don't. Hashes are mappings from _string_ to scalar. You cannot use a
reference as key.

I would probably just use a HoH instead, like
$hash{$hash_key}{Value1}
$hash($hash_key}{Value2}
And if either value doesn't exist then just don't create that hash
entry.

jue
 
B

Ben Morrow

Quoth "[email protected] said:
I am creating 2 hash tables. In the first hash table I have a string
as the key but in the second one I want the reference to that string
as the key, to save memory.

Modern versions of perl share identical hash keys between all hashes
that use that key, for exactly that reason. So: don't worry about it :).

Ben
 
X

xhoster

Hi,

I am creating 2 hash tables. In the first hash table I have a string
as the key but in the second one I want the reference to that string
as the key, to save memory.
ie.
$hash_table_one[$string_key]
^
|
$hash_table_two[$string_key_ref] -> this key is a reference to the
first table's key

Other people who have answered this took you too literally. You do want
a "Perl reference", which is what they answered, you want a conceptual
reference. And lucky for you, Perl does this for you automatically.

perl -le '$x.=rand() foreach 1..3e6; \
print +(`ps -p $$ -o rss `)[1];'
51332

perl -le '$x.=rand() foreach 1..3e6; $h{$x}=1; \
print +(`ps -p $$ -o rss `)[1];'
101164

perl -le '$x.=rand() foreach 1..3e6; $h{$x}=1; $h2{$x}=1; \
print +(`ps -p $$ -o rss `)[1];'
101156

The third example uses no additional memory over the second.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
S

szr

Gunnar said:
Not possible. Hash keys are always strings.

You be more care with the use of the phrase "Not Possible", as it is
perfectly possible to take the reference of a key. You just have to do
al lthe work of keep the 2nd ref up to date - perhaps usinga Tie module
could be of some use here.

my %h_s = ( A => 123, B => 456, C => 789);
my %h_r = map { \$_ => \$h_s{$_} } keys %h_s;
# Note, this could be the actual value,
# but a ref made more sense.

foreach my $k (keys %h_s) {
my $v = $h_s{$k};
print qq{[$k] => [$v]\n};
}
print "\n";

foreach my $k (keys %h_s) {
my $v = ${$h_r{\$k}};
print qq{[$k] => [$v]\n};
}
print "\n";


[A] => [123]
[C] => [789]
=> [456]

[A] => [123]
[C] => [789]
=> [456]


I honestly do not know of any situation where such a setup would be
useful or needed. It should also be noted that storing a ref as a hash
key effectively destroys the actual ref since it stringifies the ref and
in the 2nd for-loop, C<$h_r{\$k}>, the same thing happenes, which why
it matches. You cannot use the keys from %h_r themselves as a ref witout
doing some extra work (I'd assume some sort of crazy eval construct
would come into play.)

* * *

In conclusion, there are much better ways to go about this. Namely,
using one hash, and thus one set of keys, and use hash-or-array refs to
store your data structure.
 

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,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top