Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
I'm having trouble creating a hash in which the index
refers to an array.
Here's the array : @check2 = ($LDNvalue, $ALTvalue, $MACHvalue);
Creating the hash : %LdnLine = ($j => @check2);
When I use the following print statement
print "LdnLine = @LdnLine{$j}";
I get only the first value in the @check2 array.
However when I use
print %LdnLine;
I get the entire array.
I'm new to perl and am confused as to why these two
print statements would be different.
The only answer I can come up with is that I've screwed
up creating the hash. Help!
Re: Using an array in a hash
by btrott (Parson) on Aug 08, 2000 at 02:50 UTC
|
Your hash creation should look like this:
%LdnLine = ($j => \@check2);
The value must be a reference, not an actual array.
To answer your second question--why does it look
right when you print out the entire hash--that's because
your array is being treated as a list to initialize the
hash. It's not treated as an array value to your
key $j; the values in @check2 are used as both keys
and values in your hash. This is more clear if you
do this:
use Data::Dumper;
print Dumper \%LdnLine;
With my dummy values for @check2 and $j this
gave me
$VAR1 = {
1 => 'foo',
'bar' => 'baz'
};
Which, I'll bet, is not what you were expecting. | [reply] [d/l] [select] |
|
Just a bit of elaboration on an excellent post.
The keys and values in hashes can only be scalars, you can't
directly store a array as a value. But, you can store a refrence
to a array in a hash (a reference is a scalar) which is what
btrott's code does.
When you want to make a reference to another variable use the
\ operator.
my $ref_to_array = \@an_array;
my $ref_to_hash = \%a_hash;
my $ref_to_scalar = \$a_scalar;
Or if you don't want to make a variable and then make a reference,
you can initialize them this way.
my $ref_to_array = [1,2,3,4];
my $ref_to_hash = { 'key1' => 'val1', 'key2' => 'val2' };
my $ref_to_scalar = \"some string\n";
The contents can be retrieved like:
print $ref_to_array->[0];
print $ref_to_hash->{'some_key'};
print ${$ref_to_scalar};
All this stuff is explained in the o'reily (sp?) books in
great detail. I'd suggest getting them. :)
/\/\averick | [reply] [d/l] [select] |
|
The keys and values in hashes can only be scalars
And the keys can only be strings, not just any old scalar. A nit to pick, but an important one (which you probably already knew but that some readers may not have).
-
tye
(but my friends call me "Tye")
| [reply] |
|
To elaborate on that second part...
When you say %hash = (a => "foo", b => "bar")
perl treats the "=>" operator as a synonym for ",", so this
really looks like %hash = (a,"foo",b,"bar").
Perl knows to treat a list assigned to a hash as key/value
pairs, so this works right.
In your example, where you tried %hash = (a => (foo,bar, baz)),
perl treats the right hand side as (a,(foo,bar,baz)),
which is "flattened" into (a,foo,bar,baz),
which is then assigned to %hash,
yielding %hash{a} = "foo"
and %hash{bar} = "baz", which isn't what you wanted.
The suggestions to use references will do what you want.
| [reply] [d/l] [select] |
Re: Using an array in a hash
by young perlhopper (Scribe) on Aug 08, 2000 at 04:05 UTC
|
Instead of directly answering your question (which other people
have already done, well) I'll give you a few quick pointers
on perl references (which other people will probably also do).
First, you might want to take a look at perlref, (i.e. type
perldoc perlref), it contains a pretty good explanation of
how to use references in perl.
Basically, references are scalars, if you have a C background,
just think of them as pointers, the only difference being that
you can't do pointer arithmetic on them. (i.e. no $myref++;
or similar).
Also, since perl is not a strongly typed language, you are
responsible for keeping track of what data type a reference
points to. There's no such thing as an 'array reference' or
a 'hash reference', just a reference, which can point to either
an array or a hash.
Some examples of referencing and dereferencing
# create a 'real' array and a reference to it.
my @array = (1, 2, 3, 4);
my $reftoactualarray = \@array;
# create a reference to an anonymous array
my $reftoanonymousarray = [1, 2, 3, 4];
# both print the same thing
print @$reftoactualarray;
print @$reftoanonymousarray;
The difference between a 'real' array and an anonymous one is
that when you modify the array referenced by $reftoactualarray,
the contents of @array actually change. If you change the
array referenced by $reftoanonymousarray, nobody else will
see the changes you made. Dereferencing arrays of hashes or
hashes of arrays, or any complex data structure like that,
can get pretty hairy.
Good Luck,
Mark
Corrections welcome. | [reply] [d/l] |
|
The person asked for how to get a array back OUT OF A HASH.
None of you have answered the question.
I would like to know how to do this as well.
Here what I tried and it failed.
my @host_type= qw { a b c d e} ;
my $j = "small" ;
my %vendor_size_hash = ($j => \@host_type ) ;
print "\@vendor_size_hash{$j} \n " ;
| [reply] |
|
my @array = @{ $vendor_size_hash{$j} };
To dereference a single element in the array, use:
my $el = $vendor_size_hash{$j}[$number];
| [reply] [d/l] [select] |
|
|