Data::Dumper certainly cleared that up (I had never used this before, and this will become a favorite.)It works both ways: if you can write down your data structure in a manner that looks like Data::Dumper output, then you can be relatively sure your data is at least syntactically correct.
Anyway. If I get you right, you're reading Set One, which would result in the hash as defined in Listing 1, and then you're reading Set Two, which would alter the original hash to that it becomes the one as defined in Listing Two.
# Listing One: %hash = ( "123" => "abc", "456" => { # I'm chosing for a hashref here becaus +e "abc" => undef, # eventually we'll possibly replacing t +hose "xyz" => undef, # undefs with something else. } "789" => "abc" );
# Listing Two: %hash = ( "123" => {"abc" => "zzz"}, "456" => { "abc" => ["xxx", "yyy"], "xyz" => undef # Or [], or 0, or "", or whatev +er }, "789" => {"abc" => "xxx"} );
use strict; use warnings; use Data::Dump 'pp'; # Or Data::Dumper, but I prefer the pp output. # Note that I'm using scalars here to represent the files. # I'm using Perl's capability to use references-to-scalars # as if they were files. my $setOne = <<EOF abc 123 abc 456 abc 789 xyz 456 EOF ; my $setTwo = <<EOF xxx ==> 456->abc xxx ==> 789->abc yyy ==> 456->abc yyy ==> 456->abc zzz ==> 123->abc EOF ; my %hash; # See? Here I'm opening a file handle to read from $setOne. # Typically, you'd put "somefilename.txt" in place of \$setOne, # but this code if for demonstration purposes only. open my $fileOne, "<", \$setOne or die "Couldn't read set one: $!"; while (my $line = <$fileOne>) { chomp $line; # Goodbye, newlines characters. # It would seem like the order of values and keys is turned around # in the file for set one. That, or I misinterpreted your intentio +n. my ($value, $key) = split(/\s+/, $line); if (ref $hash{$key}) { # If $hash{"123"} already is a reference, then we can just add + the new # key to it. # Note that the name '$value' is a little misleading here, sin +ce we'll # be using it as a key... Well, such is life. $hash{$key}->{$value} = undef; } elsif (exists $hash{$key}) { # $hash{"123"} is already there, but we got another value for +it. # So we need a hash ref. Let's make one. $hash{$key} = {$hash{$key} => undef, $value => undef}; } else { # $hash{"123"} isn't there yet, so here we go rather plainly: $hash{$key} = $value; } } close $fileOne; # Let's see what we've got so far. pp \%hash; # print Dumper \%hash; # Again, I prefer pp, but there are always + multiple options. # Fine then. Let's read that other file. open my $fileTwo, "<", \$setTwo or die "Couldn't read set two: $!"; while (my $line = <$fileTwo>) { chomp $line; my ($newvalue, $key, $oldvalue) = $line =~ m/^(.+)\s+==>\s+(.+)->( +.+)$/; if (ref $hash{$key}) { # If $hash{"123"} is a reference... if (ref $hash{$key}->{$oldvalue}) { # If $hash{"123"}->{"abc"} is also a reference # Jump right to the next iteration if we've run into a dup +licate. # Since your original example didn't specify that it shoul +d take # duplicates into account. next if grep {$_ eq $newvalue} @{$hash{$key}->{$oldvalue}} +; push @{$hash{$key}->{$oldvalue}}, $newvalue; } elsif (exists $hash{$key}->{$oldvalue}) { # $hash{"123"}->{"abc"} is not a reference, even though # it already exists. if (defined $hash{$key}->{$oldvalue}) { # This means that $hash{"123"}->{"abc"} already has a +value, # so what we really need here is to convert it into an + array ref # so that it can hold multiple values. $hash{$key}->{$oldvalue} = [$hash{$key}->{$oldvalue}, +$newvalue]; } else { # $hash{"123"}->{"abc"} is undef, so we can simply rep +lace # the undef with the new value. $hash{$key}->{$oldvalue} = $newvalue; } } } else { # $hash{"123"} is not a reference yet. Let's turn it into one. $hash{$key} = {$oldvalue => $newvalue}; } } close $fileTwo; # Final results: pp \%hash;
But really, this is such a mess that I doubt this is what you want.
In reply to Re^3: (another) HoH question
by muba
in thread (another) HoH question
by zuma53
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |