in reply to How to check that keys in two hashes match and get the corresponding values
I'd suggest rethinking your data structure a bit. The reason you're having a hard time with it is that the data structure isn't regular, so your code is obfuscated by all sorts of special case handling. I couldn't tell what you're wanting to do by looking at your code.
Looking at the data, your code and the desired output gave me enough to go on, though. At first, I tried to clean up your code to get it going, but it was just too different from how I would've done it, that I kept getting confused. So I just started from scratch and came up with this:
$ cat 1028644.pl #!/usr/bin/perl use strict; use warnings; my $nfshashofhashes = { "bigstorderv_mpt" => { "%export_name" => "/bb/bigstor/derv", "%filer_device" => "nydevnfs_derv", "%filer_volume" => "/vol/derv", }, "bigstormtg_mpt" => { "%export_name" => "/bb/bigstor/mtgmodel", "%filer_device" => { "\@ridge" => "njdevnfs_mtge", "\@west" => "nydevnfs_mtge" }, "%filer_volume" => "/vol/mtge", }, "build10_mpt" => { "%export_name" => "/bb/source", "%filer_device" => { "\@ridge" => "rnap7751-s", "\@west" => "nydevnfs_sunbbsource" }, "%filer_volume" => { "\@ridge" => "/vol/sunbbsource_c", "\@west" => "/vol/sunbbsource" } }, "build11_mpt" => { "%export_name" => "/bb/source", "%filer_device" => { "fridge" => "rnap7751-s", "\@west" => "nydevnfs_sunbbsource", }, "%filer_volume" => { "\@ridge" => "/vol/sunbbsource_c", "\@west" => "/vol/sunbbsource", "qwest" => "/vol/sunquirks", } }, }; while ( my ($MPT, $rMPT) = each %{$nfshashofhashes} ) { die "MPT<$MPT> NOT A HASH!\n" unless ref $rMPT eq 'HASH'; die "MPT<$MPT> WRONG STRUCTURE!\n" unless exists $rMPT->{'%export_ +name'}; my $EXP = $rMPT->{'%export_name'}; # Set default value and hash ref for devices my ($rFILDEV, $DEVDFLT, $t); $t = $rMPT->{'%filer_device'}; if (ref $t eq 'HASH') { $rFILDEV = $t; $DEVDFLT = '????'; } else { $rFILDEV = { }; $DEVDFLT = $t; } # Same for volumes my ($rFILVOL, $VOLDFLT); $t = $rMPT->{'%filer_volume'}; if (ref $t eq 'HASH') { $rFILVOL = $t; $VOLDFLT = '????'; } else { $rFILVOL = { }; $VOLDFLT = $t; } # Match up the VOL and DEV entries in the hash. Missing values fo +r # DEV and VOL will be filled in with the DFLT values as needed. my %MATCHUP; $MATCHUP{$_}{VOL} = $rFILVOL->{$_} for keys %$rFILVOL; $MATCHUP{$_}{DEV} = $rFILDEV->{$_} for keys %$rFILDEV; # If both were scalars, MATCHUP is empty, so make a single matchin +g record $MATCHUP{'BAR'} = { DEV=>$DEVDFLT, VOL=>$VOLDFLT } if ! keys %MATC +HUP; # And our final results... for (keys %MATCHUP) { my $DEV = $MATCHUP{$_}{DEV} // $DEVDFLT; my $VOL = $MATCHUP{$_}{VOL} // $VOLDFLT; printf "%-20.20s %-20.20s %-20.20s %-20.20s\n", $MPT, $DEV, $VOL, $EXP; } } $ perl 1028644.pl bigstorderv_mpt nydevnfs_derv /vol/derv /bb/big +stor/derv build11_mpt ???? /vol/sunbbsource_c /bb/sou +rce build11_mpt rnap7751-s ???? /bb/sou +rce build11_mpt ???? /vol/sunquirks /bb/sou +rce build11_mpt nydevnfs_sunbbsource /vol/sunbbsource /bb/sou +rce build10_mpt rnap7751-s /vol/sunbbsource_c /bb/sou +rce build10_mpt nydevnfs_sunbbsource /vol/sunbbsource /bb/sou +rce bigstormtg_mpt njdevnfs_mtge /vol/mtge /bb/big +stor/mtgmodel bigstormtg_mpt nydevnfs_mtge /vol/mtge /bb/big +stor/mtgmodel
I think that'll do it for you. You didn't specify what you were expecting when you had two hashes with mismatched keys, so I added "build11_mpt" to demonstrate it. Feel free to change it as you need it.
Since I had trouble wrapping my head around your code, I fully expect you might have a little difficulty with mine, so feel free to ask questions.
...roboticus
When your only tool is a hammer, all problems look like your thumb.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: How to check that keys in two hashes match and get the corresponding values
by NewLondonPerl1 (Acolyte) on Apr 15, 2013 at 03:35 UTC | |
by roboticus (Chancellor) on Apr 15, 2013 at 12:43 UTC |