Tuna has asked for the wisdom of the Perl Monks concerning the following question:

Simple question.
open (BEG_PUB_FILE, "$as_dir/$beg_pub_file") || die "Cannot open: $!\n"; while ($pub_line = <BEG_PUB_FILE>) { chomp $pub_line; next if ($pub_line =~ /unknown|shutdown/); ($as,$as_name,$neighbor,$router,$interface,$address, $interface_name,$ifindex,$vpi,$vci) = split(' ',$pub_line); push @{$HoL_pub{$router}}, $interface_name; } foreach $pub_element(@pub) { open FILE, "$as_dir/$element" || die "Can't open $as_dir/$element: $!\n"; while ($compare_pub = <FILE>) { chomp $compare_pub; next if ($compare_pub =~ /unknown|shutdown/); ($as,$as_name,$neighbor,$router,$interface,$address, $interface_name,$ifindex,$vpi,$vci) = split(' ',$compare_lines); push @{$HoL_compare_pub{$router}}, $interface_name; } }
I need to compare both hashes, and if:

an element exists in %HoL_compare_pub but not in %HoL_pub I need to push all non-natches into another hash of array.

Replies are listed 'Best First'.
Re: Comaring contents of 2 Hash of Arrays
by dfog (Scribe) on Feb 20, 2001 at 05:59 UTC
    If I understand what you are asking correctly, all you should need to do is :
    my %Non_Matches; foreach (keys(%HoL_compare_pub)) { if (!(defined($HoL_pub{$_}))) { $Non_Matches{$_} = $HoL_compare_pub{$_}; } }
    The Non_Matched hash will contain only the value key pairs where HoL_compare_pub exists and HoL_pub doesn't. Hope this helps. Dave </code>

      No, I think that s/he means that s/he wants to compare each of the values in the arrays pointed to (via array refs) by the corresponding keys in each hash. What I can't tell is if s/he expects the items to be in the same order in each hash or not.

      If so, the most straight-forward way to do it would be something like:

      my @Non_Matching_Keys; foreach $key (keys %HoL_compare_pub) { my @orig_a = @{$HoL_pub{$key)}; my @comp_a = @{%HoL_compare_pub{$key}}; foreach(0 .. @orig_a) { if($orig_a[$_] ne $comp_a[$_]) { push @Non_Matching_Keys, $key; } } }

      Note that that is totaly untested. Also, if the order of the two arrays are different, it won't work. Maybe running a sort() on them both first would work?

      Update: Nevermind... I think I got confused by the "Hash of Arrays" part (and I was in a hurry to leave work ;-)... Looks like Tuna just wanted to see if a router (hash element) existed in one hash and not the other, just like dfog and dkubb said. =)

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

(dkubb) Re: (2) Comparing contents of 2 Hash of Arrays
by dkubb (Deacon) on Feb 20, 2001 at 09:33 UTC

    Tuna, I think this does what you want.

    If an element exists in %HoL_compare_pub, but not inside %HoL_pub, then push it into the array-ref $no_matches{$key}:

    my %no_matches; foreach my $key (keys %HoL_compare_pub) { push @{$no_matches{$key}}, $HoL_compare_pub{$key} unless exists $HoL_pub{$key}; }
      I tested your program at my site and it works:
      use strict; use CGI qw(:standard); print header; print start_html("Hash Test"); my %HoL_compare_pub=('NL','The Netherlands','BE','Belgium','DE','Germa +ny','MC','Monaco','ES','Spain'); my %HoL_pub=('NL','The Netherlands','BE','Belgium'); my %no_matches; foreach my $key (keys %HoL_compare_pub) { push @{$no_matches{$key}}, $HoL_compare_pub{$key} unless exists $HoL_pub{$key}; } foreach my $noMatchKey (keys %no_matches){ print "$noMatchKey\n"; } print end_html;

      What I don't understand is why you describe $no_matches{$key} as being an array-ref. It seems to me that it is simply an element of a hash.

      $no_matches{$key) does not seem to refer to anything outside of %no_matches. So why is it an array-ref?