Many thanks, everyone, for the useful responses.

I've had a bit of a go with some of the suggestions... and I have something that does what I need (I think - more testing required, as usual). The updated sample code follows:-

# Ref: http://www.perlmonks.com/?node_id=1196078 use Data::Dumper; %data_hash = (); %output_hash = (); @master_dsks = ( 70, 71, 75, 90, 91, 92, 93, 96, 97, 98, 99, 190, 204, 205, 550, 551 ); @master_sites = ( 350, 377, 510, 512, 580, 587, 590, 1100, 1105, 1107, 1108 ); # ---- printf("All Known Dsks:\n"); # Show ALL the known dsks foreach (@master_dsks) { printf("%s ", $_); } printf("\n\n"); # ---- printf("All Known Sites:\n"); # Show ALL the known sites foreach (@master_sites) { printf("%s ", $_); } printf("\n\n"); # ---- while( <DATA> ) { # Build list of unique (sit +e:dsk) items ($site, $buf) = split(/,/, $_); @input_item = split(/:/, $buf); foreach $input_field (@input_item) { # EX: "VAR8=36!206!207!" @dsk_list = ($input_field =~ /([0-9]+)!([0-9]+)!$/); # Get last + 2 of 3 items foreach $dsk (@dsk_list) { # Each dsk item in the inpu +t... next if ($dsk == 0); # Skip '0' dsk items $key = $site . ":" . $dsk; # Build composite key $data_hash{$key}++; # ...and save it } } } foreach $key ( sort keys %data_hash ) { # Build list of dsk -> (mul +ti sites) ($site, $dsk) = split(/:/, $key); push( @{ $output_hash{$dsk} }, $site ); # ... dsk -> (multi sites) push( @{ $site_2_dsk{$site} }, $dsk ); # !!! ADDITION !!! ... site + -> (multi dsks) } # ---- printf("List of sites for each used dsk:\n"); foreach $dsk (sort {$a <=> $b} keys %output_hash) { # Show list of si +tes for each dsk printf("Dsk: %d: ... ", $dsk); foreach $site (sort {$a <=> $b} @{$output_hash{$dsk}}) { printf(" %d ", $site); } printf("\n"); } printf("\n"); printf("List of dsks for each used site:\n"); foreach $site (sort {$a <=> $b} keys %site_2_dsk) { # Show list of ds +ks for each site printf("Site: %d: ... ", $site); foreach $dsk (sort {$a <=> $b} @{$site_2_dsk{$site}}) { printf(" %d ", $dsk); } printf("\n"); } printf("\n"); # ---- my %master_dsks_hash = map { $_ , "" } @master_dsks; # Hash of ALL d +sks delete @master_dsks_hash{keys %output_hash}; # Delete the US +ED dsks @unused_dsks = (keys %master_dsks_hash); # ...leaving th +e UNUSED dsks printf("Dsks that are known but unused:\n"); foreach (sort {$a<=>$b} @unused_dsks) { printf("%s ", $_); } printf("\n\n"); # ---- my %master_sites_hash = map { $_ , "" } @master_sites; # Hash of ALL s +ites delete @master_sites_hash{keys %site_2_dsk}; # Delete the US +ED sites @unused_sites = (keys %master_sites_hash); # ...leaving th +e UNUSED sites printf("Sites that are known but unused:\n"); foreach (sort {$a<=>$b} @unused_sites) { printf("%s ", $_); } printf("\n\n"); __DATA__ 1108,VAR6=36!204!205!:VAR8=36!206!207!:VAR13=36!70!0!:VAR14=36!70!71!: +VAR15=36!71!0! 377,VAR12=36!97!96! 512,VAR6=36!90!91!:VAR8=36!92!93!:VAR11=36!0!70!:VAR12=36!189!190! 587,VAR2=36!550!0!:VAR4=36!554!0!:VAR6=36!551!0!

....and the output:-

All Known Dsks: 70 71 75 90 91 92 93 96 97 98 99 190 204 205 550 551 All Known Sites: 350 377 510 512 580 587 590 1100 1105 1107 1108 List of sites for each used dsk: Dsk: 70: ... 512 1108 Dsk: 71: ... 1108 Dsk: 90: ... 512 Dsk: 91: ... 512 Dsk: 92: ... 512 Dsk: 93: ... 512 Dsk: 96: ... 377 Dsk: 97: ... 377 Dsk: 189: ... 512 Dsk: 190: ... 512 Dsk: 204: ... 1108 Dsk: 205: ... 1108 Dsk: 206: ... 1108 Dsk: 207: ... 1108 Dsk: 550: ... 587 Dsk: 551: ... 587 Dsk: 554: ... 587 List of dsks for each used site: Site: 377: ... 96 97 Site: 512: ... 70 90 91 92 93 189 190 Site: 587: ... 550 551 554 Site: 1108: ... 70 71 204 205 206 207 Dsks that are known but unused: 75 98 99 Sites that are known but unused: 350 510 580 590 1100 1105 1107

BTW.. Not using the 'warnings' and 'strict' pragmas is fair enough comment.. but this is isolated, sample code... so I'm not too fussed about using them in this context.

Similarly, as I've been cutting code since the 1970s or something, I tend to pre-declare constants, variables, etc at the top of a block or module and then I know where to find all the initializations and comments about the identifiers I use in the code... instead of trying to find the 'first instance' (the 'my' declaration) of an identifier's use in some part of a mass of code when debugging/trying to understand some code - 'tis just easier for me.

..and Re: the issue of 'exists' ... trying to understand the perldoc description gives me too much of a headache:-

...but I take the point.

Thanks again for the most useful posts.


In reply to Re: How to Check Hashes for Missing Items when Keys can be Values and vice versa by ozboomer
in thread How to Check Hashes for Missing Items when Keys can be Values and vice versa by ozboomer

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.