techie
techie

Reputation: 59

How can multiple hash values be retrieved using perl?

How can multiple hash values be retrieved? I tried using use Hash::MultiValue and get_all(). It throws an error saying "Can't call method "get_all" on an undefined value" . Which is the better option to implement this functionality of multiple values for a particular key ? The value of the key is the file that is being opened.

use warnings;
use List::MoreUtils qw(firstidx);
use Hash::MultiValue;

my $key_in;
…
open ($FR, "<$i") or die "couldn't open list";
 while($line=<$FR>){ 
   if($line =~ /search_pattern/){
   my $idx = firstidx { $_ eq 'hash_key' } @tags;   
   my $key= @tags[$idx+1];
   $hash{$key}= Hash::MultiValue->new($key=>'$i');
} 
close($FR);
for my $key_in ( sort keys %hash ) {
    @key_in = $hash->get_all('$key_in');
    print "$key_in = $hash{$key_in}\n";
}
my $key_in = <STDIN>;
if (exists($hash{$key_in})){
$hash_value = $hash{$key_in};
}else{
    exit;
}

Upvotes: 0

Views: 617

Answers (2)

brian d foy
brian d foy

Reputation: 132812

I think you want an array reference for the value. You can then treat that as an array. This is the sort of stuff we show you in Intermediate Perl:

 $hash{$key} = [];
 push @{ $hash{$key} }, $some_value;

 my @values = @{ $hash{$key} };

With Perl v5.24, you can use postfix dereferencing to make it a bit prettier:

 use v5.24;

 $hash{$key} = [];
 push $hash{$key}->@*, 'foo';
 push $hash{$key}->@*, 'bar';

 my @values = $hash{$key}->@*;

And, since Perl automatically takes an undefined value and turns it into the reference structure you need (auto vivification), you don't need to initialize an undefined value:

 use v5.24;

 push $hash{$key}->@*, 'foo';
 push $hash{$key}->@*, 'bar';

 my @values = $hash{$key}->@*;

Get all the keys of a hash:

my @keys = keys %hash;

Get all of the values (in the order of the corresponding keys if you haven't changed the hash since you called keys):

my @values = values %keys;

Get some values with a hash slice:

my @some_values = @hash{@some_keys};

Get some keys and values (key-value slice):

use v5.20;
my %smaller_hash = %hash{@some_keys}

Upvotes: 2

H&#229;kon H&#230;gland
H&#229;kon H&#230;gland

Reputation: 40758

Here is an example of how you can use get_all() from Hash::MultiValue to retrive multiple hash values for a given key:

use strict;
use warnings;
use Data::Dumper qw(Dumper);
use Hash::MultiValue;

my $hash = Hash::MultiValue->new();
$hash->add(tag1 => 'file1');
$hash->add(tag1 => 'file2');
$hash->add(tag2 => 'file3');
my @foo = $hash->get_all('tag1');
print(Dumper(\@foo));

Output:

$VAR1 = [
          'file1',
          'file2'
        ];

Upvotes: 1

Related Questions