Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: How to Check Hashes for Missing Items when Keys can be Values and vice versa

by ozboomer (Friar)
on Jul 26, 2017 at 12:07 UTC ( [id://1196096]=note: print w/replies, xml ) Need Help??


in reply to How to Check Hashes for Missing Items when Keys can be Values and vice versa

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:-

    A hash or array element can be true only if it's defined and defined only if it exists, but the reverse doesn't necessarily hold true.

...but I take the point.

Thanks again for the most useful posts.

Replies are listed 'Best First'.
Re^2: How to Check Hashes for Missing Items when Keys can be Values and vice versa
by choroba (Cardinal) on Jul 26, 2017 at 12:26 UTC
    > I know where to find all the initializations and comments about the identifiers

    With good variable names, no comments are needed. And there shouldn't be a block larger than one screen, so you don't have to scroll to find the initialization. See Skimmable Code by schwern.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re^2: How to Check Hashes for Missing Items when Keys can be Values and vice versa
by BillKSmith (Monsignor) on Jul 26, 2017 at 13:18 UTC
    I agree that you habit of pre-declaring variables largely defeats the advantage of using strict (although it is still useful in detecting misspelled variables). Your suggestion of defining them at "first instance" is not much better. If fact, it can introduce errors (which strict can detect). A better strategy is to declare all variables in the "smallest possible scope". This does require some effort in writing new code and it does little to help your reader find the declarations. The advantage to you is that it greatly reduces the possibility of misusing a variable. The advantage to your reader is that, when he comes to the end of the scope, he knows for certain that he has seen all the references to the variable.
    Bill
Re^2: How to Check Hashes for Missing Items when Keys can be Values and vice versa
by pryrt (Abbot) on Jul 26, 2017 at 13:31 UTC

    trying to understand the perldoc description givees me too much of a headache:-

    A hash or array element can be true only if it's defined and defined only if it exists, but the reverse doesn't necessarily hold true.

    here's a Venn(ish) diagram in beautiful ASCII art that may or may not help, with examples on the side

    universe of possible hash elements in Perl +--------------------------------------+ | elements that exist | $hash{element_exis +ts}; # this example: exists, undefined, false | +--------------------------------+ | | | elements that are defined | | $hash{element_defi +ned} = function_def();# this example: exists, defined, unknown false/ +true | | +--------------------------+ | | | | | elements that are true | | | $hash{element_true +} = 1; # this example: exists, defined, true | | +--------------------------+ | | | | | | | | +--------------------------+ | | | | : elements that are false : | | $hash{element_fals +e} = function_false();# this example: exists, defined, false | | : +-------------------+ : | | | | : | false but defined | : | | $hash{element_fals +e_defined} = 0; # this example: exists, defined, false | | : +-------------------+ : | | | +--:--------------------------:--+ | | : : | | +--:--------------------------:--+ | | | : +-------------------+ : | | | | : | false but undef | : | | $hash{element_fals +e_undefined} = undef; # this example: exists, undefined, false | | : +-------------------+ : | | | | +--------------------------+ | | | | elements that are undefined | | $hash{element_unde +fined}; # this example: exists, undefined, false | +--------------------------------+ | +--------------------------------------+

    Note that the ASCII art combined with wanting space for labels sometimes implies there is room in the Perl universe for combinations that aren't actually possible: for example, there are no elements that are undefined but not false, because perl coerces undefined to false.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1196096]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (9)
As of 2024-04-18 11:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found