http://qs321.pair.com?node_id=691095


in reply to Common hash keys

OK, let's walk through this.

A hash reference is just a reference to a hash, getting at the hash is a simple matter -- so we can ignore the "reference" part of your question for now, and focus on how to determine if two hashes share any keys. Let's start with two simple hashes:

%a = ( one=>1, two=>2, three=> 3 ); %b = ( two=>'two', three=>'three', four=>'four');

We know the keys they have in common are two and three, but how to find that out in code?

First, let's rephrase the question a little bit: if I know all the keys in one hash, how do I find out if any of those keys exist in another hash?

Let's work backwards from that. How do we find out if the %a hash contains a key -- let's say, the key one? That would be exists:

if (exists $a{one}) { print "\%a has 'one' for a key" }

Ok, so how do we find out what keys a hash has? How about keys:

print join(",", keys %a); # prints "one,two,three"

So, if we get the list of keys for hash %a, all we have to do is loop through them and see if %b has any that match. Here's the long way:

my @common_keys; foreach my $key (keys %a) { if (exists $b{$key}) { print "\%a and \%b have key '$key' in common\n"; push @common_keys, $key; } }

Make sense? Of course, this type of activity -- looking through a list to find items that meet a criterion -- is so common that Perl has a function for it: grep. So here's a short version:

my @common_keys = grep { exists $b{$_} } keys(%a);

Now let's add "references" back to the mix. Let's make references to our hashes:

$x = \%a; $y = \%b;

Now, we do as above, but dereferencing as appropriate:

my @common_keys = grep { exists $y->{$_} } keys( %{ $x } );

We pass the whole hash referenced by $x to keys; and we use the dereference operator -> to make sure that exists looks at the hash referenced by $y.

<radiant.matrix>
Ramblings and references
“A positive attitude may not solve all your problems, but it will annoy enough people to make it worth the effort.” — Herm Albright
I haven't found a problem yet that can't be solved by a well-placed trebuchet