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

Hi,

I have successfully built a hash table and have two separate keys that I need to manage. I want to do the following:

list1 = (a b c d e f g)
list2 = (a b c d e f g)

key1 = (a b c)
key2 = (f g)

If key1 is matched between list1 and list2 write to a file. Then, after the key1 match is made, check if key2 is NOT matched between list1 and list2 then write to another file.

Here is a snippet of code I currently have:-

$AstPDSlackHash{$aststartendwclks} = join (" ",$aststartendwclks,$astp +dslack); $PTPDSlackHash{$ptstartendwclks} = join (" ",$ptstartendwclks,$ptpdsla +ck);<br> foreach (keys %AstPDSlackHash) { print XLOUT ("$AstPDSlackHash{$_} $PTPDSlackHash{$_}\n") if exists + $PTPDSlackHash{$_}; }

What is the best way to do a second match with my second key? In other words, instead of printing to a file named XLOUT, stash the match in something (?) and then scrub that something with the second key. When the second keys do not match, write to a second file.

Here is my second set of keys:-
for ($i = 7; $i <= $astlast; $i++) {$astmasterlist = join (" ",$astmat +erlist,$in2sal&#91$i&#93); } for ($i = 7; $i <= $ptlast; $i++) {$ptmasterlist = join (" ",$ptmaster +list,$in2sal&#91$i&#93);}
GOAL: Take the keys $ptmasterlist and $astmasterlist and make sure they match in the original hash, but don't bother looking at anything that doesn't end up in XLOUT.

Here's my best guess:-
$AstPDSlackHash{$aststartendwclks,$astmasterlist} = join (" ",$aststar +tendwclks,$astpdslack,$astmasterlist); $PTPDSlackHash{$ptstartendwclks,$ptmasterlist} = join (" ",$ptstartend +wclks,$ptpdslack,$ptmasterlist); foreach ($astmasterlist %AstPDSlackHash) { print XLOUT2 ("$AstPDSlackHash{$_} $PTPDSlackHash{$_}\n") if $ptma +sterlist !exists $PTPDSlackHash{$_}; }

But I know that is wrong...

My god, why is this so hard to explain? Need more java...

Thanks!

Janitored by holli - added code tags

Replies are listed 'Best First'.
Re: Managing multiple keys in a hash table...
by Joost (Canon) on Jun 02, 2005 at 17:36 UTC
Re: Managing multiple keys in a hash table...
by mayhem (Hermit) on Jun 02, 2005 at 17:50 UTC
    I also found this quite difficult to understand. I assumed your lists were arrays and that your keys were stored in hashes. Following those assumptions i producted this:
    my @list1 = qw/a b c d e f g/; my @list2 = qw/a b c d e /; my %one = ( a => 1, b => 1, c => 1 ); my %two = ( f => 1, g => 1 ); for my $key ( keys %one ) { if ( grep {$_ eq $key} @list1 and grep {$_ eq $key} @list2) { print +"File 1 $key", $/ } } for my $key ( keys %two ) { unless ( grep {$_ eq $key} @list1 and grep {$_ eq $key} @list2 ) { if ( grep {$_ eq $key} @list1 or grep {$_ eq $key} @list2 ) { print "File 2 $key", $/; } } }
    This will work for: "If key1 is matched between list1 and list2 write to a file. Then, after the key1 match is made, check if key2 is NOT matched between list1 and list2 then write to another file" Although it is hard to follow what exactly you have set up, or i could provide a more thorough answer. Hope this helps a little bit!

      If don't know if your solution does the right thing or not, but I do know it can be optimized. What follows does exactly the same thing as yours, except it does it in O(n) time instead of O(n*n)

      my @list1 = qw/a b c d e f g/; my @list2 = qw/a b c d e /; my %one = ( a => 1, b => 1, c => 1 ); my %two = ( f => 1, g => 1 ); my %list1; undef @list1{@list1}; my %list2; undef @list2{@list2}; foreach my $key (keys %one) { if (exists $list1{$key} && exists $list2{$key}) { print "File 1 $key", $/; } } foreach my $key (keys %two) { unless (exists $list1{$key} && exists $list2{$key}) { if (exists $list1{$key} || exists $list2{$key}) { print "File 2 $key", $/; } } }