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

For what it's worth.. and I don't know if it's "too clever for my own good", here's something I've built to assist in the creation of the '2-way' structures.

...and all I'll need to do as time goes on is add to the conditional where there's a '@B_list = ' in the code...

Just for the curious :) ...

# -------------------------------------------------------------------- +-------------- # Build_Joined_Hashes - Build hashes to assist '2-way' queries # # Description: # Create hashes where B -> (A1, A2, ...) and A -> (B1, B2, ...) # That is: # 1. given B, get a list of A's that refer to B # 2. given A, get a list of B's that refer to A # # Uses Globals: # # Notes: # - VP DSK hash: 2324(LX INT) -> VAR2=36!550!0!:VAR4=36!554!0!:VAR6 +=36!551!0! # - TC DSK hash: 9705(LX TC) -> 11,13-JAN-2014:13-JAN-2014 # -------------------------------------------------------------------- +-------------- sub Build_Joined_Hashes { my ($input_hash_ref, $type, $A_B_hash_ref, $B_A_hash_ref) = @_; my ($buf, $A_item, $input_field, $B_item, $key); my (@input_item, @B_list); my (%tmp_hash); %tmp_hash = (); # hash: A:B -> (count) %$A_B_hash_ref = (); # List of Bs that are used in As %$B_A_hash_ref = (); # List of As that are used in Bs foreach $A_item (keys %$input_hash_ref) { # For each 'A' +item... $buf = $$input_hash_ref{$A_item}; # ..get 'B usag +e list' record @input_item = split(/:/, $buf); # Get each 'B u +sage' item foreach $input_field (@input_item) { # For each 'B u +sage' item... if ($type eq "VAR") { # Get list of ' +B' instances... @B_list = ($input_field =~ # ... when VAR. +.. /([0-9]+)!([0-9]+)!$/); } elsif ($type eq "TC") { @B_list = ($input_field =~ # ... when TC.. +. /^([0-9]+),/); } foreach $B_item (@B_list) { # Each 'B' inst +ance... next if ($B_item == 0); # Skip '0' item +s $key = $A_item . ":" . $B_item; # Make composit +e key: A:B -> (count) $tmp_hash{$key}++; } } } foreach $key ( sort keys %tmp_hash ) { # For every 'B +usage in A' instance... ($A_item, $B_item) = split(/:/, $key); push( @{ $$A_B_hash_ref{$B_item} }, $A_item ); # Build list of + B -> (A1, A2, ...) push( @{ $$B_A_hash_ref{$A_item} }, $B_item ); # ... and + A -> (B1, B2, ...) } return; } # end Build_Joined_Hashes

Perhaps it would be a better approach(?) to simply do things using DBD::CSV and treat everything as a database(!) and use SQL or sumfin'...

  • Comment on Re: How to Check Hashes for Missing Items when Keys can be Values and vice versa
  • Download Code