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

Hello, monks!
I'm another young perl monk, seekeng for some wisdom here.
Here is my question:
I have a hash %h1, and an array @a1 with some keys from %h1. As a result I need to get another array @a2:
foreach my $tmp (@a1){ push @a2, $h1{$tmp}; }
Is there some better way that will do the job?
Thanks,
Twinsen.

Edit by tye, title, CODE tags

Replies are listed 'Best First'.
Re: Need help
by robartes (Priest) on Mar 24, 2003 at 17:30 UTC
    This can be done using hash slices. Basically prefix the hash variable name with the @ sigil and instead of the key, give it a list of keys. Here's an example:
    use strict; use Data::Dumper; my %h1=( 'camel' => 'flea', 'frog' => 'green', 'jabberwocky' => 'eh?', ); my @a1=qw/frog camel/; # Hash slice is on the right hand side of assignment below my @a2=@h1{@a1}; print Dumper(\@a2); __END__ $VAR1 = [ 'green', 'flea' ];

    CU
    Robartes-

      It worked! Great, thank you! :)

      -Twinsen
Re: getting array of values from hash
by adrianh (Chancellor) on Mar 24, 2003 at 17:33 UTC
    Is there some better way that will do the job?

    Yes there is, it's called a hash slice. In general:

    @values = @hash{@keys};

    so for your example

    @a2 = @h1{@a1};
Re: getting array of values from hash
by Limbic~Region (Chancellor) on Mar 24, 2003 at 17:41 UTC
    twinsen,
    I hesitated to reply because I knew other monks would come up with a solution faster than I. I only would like to add grep for the possibility that the first array (@a1) contain non-keys as well.

    #!/usr/bin/perl -w use strict; my %h1; $h1{'key1'} = 'foo'; $h1{'key2'} = 'bar'; my @a1 = ( 'key1' , 'key2' , 'not_a_key'); my @a2 = grep defined , @h1{@a1}; print "$_\n" foreach(@a2);

    Cheers - L~R

      I hesitated to reply because I knew other monks would come up with a solution faster than I. I only would like to add grep for the possibility that the first array (@a1) contain non-keys as well.

      Niggle :-)

      This doesn't check for non-keys. It checks that each key has a defined value. In the process it auto-vivifies each key in @a1, which is probably not what you want even if you are searching for keys with defined values. For example, after running your example %h1 will be:

      ( 'key2' => 'bar', 'key1' => 'foo', 'not_a_key' => undef, )

      Also, what if you want a key with an undef value?

      If @a1 might contain non-keys they something like this will do the job.

      @a2 = @h1{grep exists $h1{$_}, @a1};
        adrianh,
        I jokingly said in the CB the other day that I wished Perl 6 would have a plug-in (literally), so that I could plug it into my brain and have it directly translate my thoughts to code. I guess I don't need to wait for Perl 6 - just have you around ;-)

        Thanks for writing what I was thinking!

        Cheers - L~R