Shawn H Corey <shawnhco...@gmail.com> writes: > Harry Putnam wrote: >> But, is there an easier way? > > Invert both hashes and find the keys in both inverses.
Shawn, hoping to pester you once more about this topic. first: Hashes involved are built like this (Using File::Find nomenclature): (NOT CODE... Just description) use File::Find; %d1h is made up like this this is key this is value $File::Find::name = $_ # ./dir1/sub/fname = fname %d2h is made up the same way: this is key this is value $File::Find::name = $_ # ./dir2/what/sub/fname = fname Also keeping in mind there are many thousands of lines in both hashs. There will be many many ways the path part of those names will differ, and only some will actually match on the ends (the values in hash terms) like the two above. Many more will be different, but the objective here is to find those that matches. I've found after many hours of tinkering and bugging the heck out of patient posters here, what I think you were trying to tell me in this thread. I wasn't capable yet of understanding it all. I'm still not but quite a lot more now has finally wormed into my pea brain. So cutting to the chase, I try to take advantage of your inversion code. It seems to work well, but I'm not confident enough to know if there are possible hidden gotchas someone with more experience might see right off the bat. ------- --------- ---=--- --------- -------- Some selective output first: [...] d1 ./dir1/etc/images/gnus/exit-summ.xpm d2 (1) ./dir2/etc/images/gnus/exit-summ.xpm d1 ./dir1/etc/images/gnus/reply.xpm d2 (1) ./dir2/etc/images/mail/reply.xpm d2 (2) ./dir2/etc/images/gnus/reply.xpm d1 ./dir1/etc/images/gnus/README d2 (1) ./dir2/src/m/README d2 (2) ./dir2/etc/e/README [...] d2 (47) ./dir2/doc/lispintro/README d1 ./dir1/lisp/gnus-util.el d2 (1) ./dir2/lisp/gnus/gnus-util.el [...] ------- 8< snip ---------- 8< snip ---------- 8<snip ------- #!/usr/local/bin/perl use strict; use warnings; use File::Find; #use diagnostics; my %d1h; my %d2h; my $d1tag = 'd1'; my $d2tag = 'd2'; ## Make sure we are feed two directory names ( my ( $d1, $d2 ) = @ARGV ) == 2 or die "\nUsage: $0 ./dir1 ./dir2\n"; ## Make sure incoming directory names exist for ($d1, $d2 ){ ( -d ) or die "<$_> cannot be found on the file system"; } ## Build the hashs find sub { return unless -f; $d1h{ $File::Find::name } = $_; },$d1; find sub { return unless -f; $d2h{ $File::Find::name } = $_; },$d2; ## Invert 1 hash and it needs to be the second one on cmd line my %inv_d2h = invert( \%d2h ); sub invert { my $h = shift @_; my %inv = (); while( my ( $k, $v ) = each %{ $h } ){ push @{ $inv{$v} }, $k; } return %inv; } ## Could have used `values' of %d1h here for $value (values %d1h) ## and avoided things like `...@{ $inv_d2h{ $d1h{ $key } } }', ## which would then be `...@{ $inv_d2h{ $value } }' but would ## not then have such ready access to the `keys' which are ## needed here too, and will be needed later on (not shown here) ## for now we just print to show how it works. foreach my $key ( keys %d1h ){ if(exists $inv_d2h{ $d1h{ $key } }){ print " $d1tag $key\n"; ## separate counter to keep (my) confusion down my $matchcnt = 0; for ( @{ $inv_d2h{ $d1h{ $key } } } ) { print " $d2tag (" . ++$matchcnt .") $_\n"; } print "\n"; } } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/