Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Creating a hash from two arrays

by simeon2000 (Monk)
on Mar 27, 2002 at 16:14 UTC ( [id://154702]=perlquestion: print w/replies, xml ) Need Help??

simeon2000 has asked for the wisdom of the Perl Monks concerning the following question:

If this question is answered in a FAQ, please forgive and point me to the answer, but I couldn't find it in the Camel book.

I've got two arrays.

@keys = qw/size atime ctime/; @vals = (101, 12, 13);

The end result I want is:

%hash = ('size' => 101, 'atime' => 12, 'ctime' => 13);

Is there a one/two liner to combine those two arrays into a hash? I can make a simple for loop to do it, but I'd like to do it in a one liner and impress all my friends and relatives. Anyone?

Replies are listed 'Best First'.
(Ovid) Re: Creating a hash from two arrays
by Ovid (Cardinal) on Mar 27, 2002 at 16:29 UTC

    I'd create a sub for it. That way, you can do a bit of extra validation and it becomes more self-documenting:

    use strict; use Carp; use Data::Dumper; my @keys = qw/size atime ctime/; my @vals = (101, 12, 13); my $hash_ref = hash_from_arrays( \@keys, \@vals ); print Dumper $hash_ref; sub hash_from_arrays { my ( $keys, $values ) = @_; croak "Mismatched number of keys and values" if @$keys != @$values +; my %hash; @hash{ @$keys } = @$values; return \%hash; }

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      ++ Ovid

      I like how you tend to write answers to code questions while keeping your eye on the big picture. If I were working on a project with other coders, I would be absolutely thrilled if some of them were as careful and aware as you are.

      I think that sometimes Perl needs the extra diligence, not because of any inherent design flaw, but because it's so flexible and doesn't enforce very strict type checking. Anyway, nice post.

      ovid,

      One question...In the code you list, the hash is created via my in the sub, yet it's available outside the sub when the sub ends. I assume that it's not destroyed when the subroutine ends because it's still being referenced?

      my first inclination would be to create the hash and pass a reference into the sub, assuming that would ensure it's availablity when the sub ends. (Aparently I am assuming wrong, and have learned a new thing! :)

        wardk asked:

        In the code you list, the hash is created via my in the sub, yet it's available outside the sub when the sub ends. I assume that it's not destroyed when the subroutine ends because it's still being referenced?

        Your assumption is correct. Variables are garbage collected when their reference count drops to zero. When the hash in the sub is declared with my, it has a reference count of one. When the reference to it is created, that reference has a reference count of one and the hash (now referred to as the "referent", or thing being referred to) has a reference of two. When the reference is returned, the original variable goes out of scope, setting the reference count down to one again.

        Note that there are two reference counts here. The $hash_ref variable has a reference count (at that point) of one and the referent (the hash we were pointing to) has a reference of one. Got that? It takes a while to get it all straight, but the process is fairly straightforward.

        wardk also wrote:

        my first inclination would be to create the hash and pass a reference into the sub, assuming that would ensure it's availablity when the sub ends.

        There are two difficulties with that approach. The first is that this is atypical behavior that tends to confuse newer programmers. For example, how many times have you seen someone ask what is wrong with this:

        $var = chomp $var;

        That usually sets $var to 1 (one) because chomp returns the number of characters removed. Most perl functions take an argument but don't change it.

        The other problem is code that quietly munges its arguments can cause all sorts of bugs for the unwary. For example, what if you passed in a hash that already had data and were expecting another one returned? That sort of stuff is very easy to misunderstand. Typical behavior for subroutines is to copy the arguments into new, non-aliased variables, do their stuff, and then return the results.

        Cheers,
        Ovid

        Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

perldoc perldata
by Fletch (Bishop) on Mar 27, 2002 at 16:25 UTC
Re: Creating a hash from two arrays
by particle (Vicar) on Mar 27, 2002 at 17:01 UTC
    create and initialize, all on one line. and annoy all those pesky people maintaining your code.

    by the way, i found this here, a long time ago--it's not my code. i kept it because it shows an interesting use of references and for

    @$_{@keys}=@values for \my %hash;

    ~Particle ;Þ

Re: Creating a hash from two arrays
by insensate (Hermit) on Mar 27, 2002 at 16:42 UTC
    Your charm and wit should serve to impress your friends...But it's nice to have a perl surrogate. Remember, impress and annoy are not discernibly dissimilar. :-D
    @numbers=(4,5,6); @keys = qw/size atime ctime/; map{$myHash{$_}=$numbers[$i];$i++}@keys;
    -Jason

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-03-29 15:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found