Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: (another) HoH question

by muba (Priest)
on Jun 23, 2012 at 18:27 UTC ( #977996=note: print w/ replies, xml ) Need Help??


in reply to (another) HoH question

Because you can assign only one scalar value to a hash slot. So you can say $hash{tree} = 4; or you can say $hash{tree} = {apple => 6}; 1, but not both at the same time.

1: This which would assign a scalar to $hash{tree}, that scalar being a reference to the anonymous hash {apple=>6}. In a way this boils down to the same as $hash->{tree}->{apple} $hash{tree}->{apple} (Update: typo kindly pointed out by AnomalousMonk), see for yourself:

use strict; use warnings; use Data::Dump 'pp'; my %hash; $hash{tree}->{apple} = 6; pp \%hash; $hash{tree} = {apple => 6}; pp \%hash; __END__ { tree => { apple => 6 } } { tree => { apple => 6 } }

If you really need a tree structure, perhaps a hash of arrays would be better suited. It'd get something like this:

use strict; use warnings; use Data::Dump 'pp'; my %hash; $hash{tree} = [4]; push @{$hash{tree}}, {apple => [6]}; pp \%hash; my $apple_tree = $hash{tree}->[1]->{apple}; push @$apple_tree, {red => 9, fuju => 4}; pp \%hash; __END__ { tree => [4, { apple => [6] }] } { tree => [4, { apple => [6, { fuju => 4, red => 9 }] }] }

Or, if you really want your own code to walk over this tree:

for my $key (keys %hash) { my ($root_value, $subtree) = @{$hash{$key}}; print "$key $root_value\n"; for my $subtree_key (keys %$subtree) { my ($subtree_root_value, $subtree_subtree) = @{$subtree->{$sub +tree_key}}; print "$key $subtree_key $subtree_root_value\n"; for my $bottom_level_key (keys %$subtree_subtree) { print "$key $subtree_key $bottom_level_key ", $subtree_ +subtree->{$bottom_level_key}, "\n"; } } } __END__ tree 4 tree apple 6 tree apple fuju 4 tree apple red 9
But as you can see that becomes pretty messy rather quickly, codewise. Perhaps you should reconsider the data structure you want to use?


Comment on Re: (another) HoH question
Select or Download Code
Re^2: (another) HoH question
by zuma53 (Beadle) on Jun 23, 2012 at 18:57 UTC
    Thanks for your answers!

    I had a vague sense that something was blocking either the level-1 assignments or level-3 assignments. Data::Dumper certainly cleared that up (I had never used this before, and this will become a favorite.)

    What I'm trying to do is use a hash to do a hash to merge two sets:

    Set 1: I have a text file establishing the universe of accepted values:
    abc 123 abc 456 abc 789 xyz 456 Hash: 123->abc 456->abc 456->xyz 789->abc
    Set 2: A set of values pointing to the hash. There may be multiple recs pointing to a hash rec (that's OK, as I just need to know of the existence of one). There maybe hash records that no one uses.
    xxx ==> 456->abc xxx ==> 789->abc yyy ==> 456->abc yyy ==> 456->abc (a dup) zzz ==> 123->abc Resulting hash 123->abc->zzz 456->abc->xxx 456->abc->yyy 456->xyz 789->abc->xxx
    I could just hash the second set, but I won't get the non-use ones like 456->xyz.

    I've tried building the first hash and using arrays for the latter hash, but it runs rather slowly from all the repeated scans.

    Suggestions appreciated.

      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"} );

      But really, this is such a mess that I doubt this is what you want.

        Actually, this does come close to what I was looking for. Understanding it, however, is another matter. LOL.

        I will give it a try.

        Thanks for your help, everyone.

      By confining the structure to hashes and avoiding arrays you don't have to worry about duplicates and, by always pre-assigning an anoymous hash, you can also dispense with the bother of turning a scalar value into a hash or an array. I think this is a little simpler and clearer than muba's solution if the structure produced is what you are after.

      use strict; use warnings; use Data::Dumper; open my $univFH, q{<}, \ <<EOD or die qq{open: < HEREDOC: $!\n}; abc 123 abc 456 abc 789 xyz 456 EOD my %univ; while ( <$univFH> ) { my( $lev2Key, $lev1Key ) = split; $univ{ $lev1Key }->{ $lev2Key } = {}; } close $univFH or die qq{close: < HEREDOC: $!\n}; print Data::Dumper->Dumpxs( [ \ %univ ], [ qw{ *univ } ] ); open my $valuesFH, q{<}, \ <<EOD or die qq{open: < HEREDOC: $!\n}; xxx ==> 456->abc xxx ==> 789->abc yyy ==> 456->abc yyy ==> 456->abc zzz ==> 123->abc EOD while ( <$valuesFH> ) { chomp; my( $lev3Key, $upperKeys ) = split m{\s*==>\s*}; my( $lev1Key, $lev2Key) = split m{->}, $upperKeys; $univ{ $lev1Key }->{ $lev2Key }->{ $lev3Key } = 1; } close $valuesFH or die qq{close: < HEREDOC: $!\n}; print Data::Dumper->Dumpxs( [ \ %univ ], [ qw{ *univ } ] );

      The Data::Dumper output, first of the structure after reading the universe file and second after reading the values file and adding its data.

      %univ = ( '456' => { 'abc' => {}, 'xyz' => {} }, '123' => { 'abc' => {} }, '789' => { 'abc' => {} } ); %univ = ( '456' => { 'abc' => { 'xxx' => 1, 'yyy' => 1 }, 'xyz' => {} }, '123' => { 'abc' => { 'zzz' => 1 } }, '789' => { 'abc' => { 'xxx' => 1 } } );

      I hope this is helpful.

      Cheers,

      JohnGG

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (9)
As of 2014-08-28 06:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (257 votes), past polls