0

I have a hash of arrays like this:

my @array1 = ("one", "two", "three", "four", "five");
my @array2 = ("banana", "pear", "apple");

my %hash = (
    numbers => \@array1,
    fruit => \@array2
);

I would like to use an element of the array to access the key. So for example, if I have "banana", I would like to print "fruit".

However when I do print $hash{banana} I get "use of unitialized value in print". How do I properly access this?

5
  • Hash lookup, just like array lookup, is one-directional. Given a key you can find the corresponding value directly, but using a value to find a key doesn't work, and you would have to write a search. Commented Mar 25, 2017 at 17:07
  • is there any way to flip it so that I could have multiple keys for the same value? Commented Mar 25, 2017 at 17:10
  • The values of a hash are independent, but you can set them to the same value. You could build a hash with eight keys—the strings in your arrays—and either numbers or fruit as values. Commented Mar 25, 2017 at 17:14
  • Okay, thanks for your help. The only problem I see is that the arrays will not be the same every time so I am unable to add them permanently as keys. Commented Mar 25, 2017 at 17:22
  • Then you need to build your hash at run time in a for loop, or using map as in the answer below. Commented Mar 25, 2017 at 17:30

2 Answers 2

1

As already mentioned by Borodin in the comments, there is no direct way to accomplish this. But you could do it in the following way:

sub getKeyByValue {
    my ($hashref, $val) = @_; # get sub arguments
    for (keys %$hashref) {
        # find key by value and give back the key
        return $_ if grep $_ eq $val, @{$hashref->{$_}};
    }
    return undef; # value not found
}

my $key = getKeyByValue(\%hash, 'banana');
print $key;

Output: fruit

Just give the hash reference and your desired value to the subroutine getKeyByValue() and it will return the corresponding key. If the value can't be found, the subroutine will return the undefined value undef. If your data structure is really big, this trivial search is obviously not the most efficient solution.

Note: If the value banana is stored several times (under more than one key), then this subroutine will of course only return the first random match (key). You have to modify the subroutine if you are interested in all the keys under which banana is possibly stored.

There are many ways to do this, like most of the time in Perl. For example you could reverse the hash and create a new one (see example in perlfaq4).

Sign up to request clarification or add additional context in comments.

Comments

0

You could create two distinct hashes:

my %hash1 = map { $_ => "numbers" } @array1;
my %hash2 = map { $_ => "fruit" } @array2;

and concatenate them:

my %hash = (%hash1, %hash2);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.