Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Using an array in a hash

by Anonymous Monk
on Aug 08, 2000 at 02:44 UTC ( #26684=perlquestion: print w/replies, xml ) Need Help??

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!

Replies are listed 'Best First'.
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.
      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. :)


        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")
      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.

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,

    Corrections welcome.

      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 " ;
        There are two ways to dereference an array, depending on what you need to do. See perlref and perlreftut for the details.

        In short, to dereference an entire array, use:

        my @array = @{ $vendor_size_hash{$j} };
        To dereference a single element in the array, use:
        my $el = $vendor_size_hash{$j}[$number];

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://26684]
Approved by root
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2023-12-11 01:50 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (41 votes). Check out past polls.