in reply to Re: Save hash value?
in thread Save hash value?

Great code, but I don't understand how an HoH will prevent multiple entries with the same name? What I am doing is that I am reading a file with stats, and then I want to merge any doublets with the same name. Then I will write the new stats to a new file. I have got my code working atm, though I will be making optimizations to it from what is written here. To start with I will use chromatics solution to begin with :)

Replies are listed 'Best First'.
Re^3: Save hash value?
by Marshall (Canon) on Jun 06, 2011 at 21:21 UTC
    I don't understand how an HoH will prevent multiple entries with the same name?
    In a plain hash, there are unique hash keys and each of them has an associated value e.g. Bob => 23. The key Bob must be unique (it can only appear once). When you have a Hash of Hash (HoH), instead of say Bob's value of 23, this is replaced by a reference to another hash. The main key "Bob" still has to be unique - nothing really changed except than instead of a numeric value of 23, I put a reference to another hash.

    I printed the HoH for you using the Data::Dump function pp()....

    my %HoH = ( Bennie => { deaths => 1, kills => 13 }, Bob => { deaths => 12, kills => 15 }, Jane => { deaths => 0, kills => 30 }, mary => { deaths => 4, kills => 20 }, );
    keys(%HoH) are: Bennie,Bob,Jane,mary (note case matters!). The value of those keys are references to anonymous hashes (hashes which have no specific name of their own). Each one of those hashes contains key/value pairs for deaths and kills. If you write:
    $playerHoH{Harry}{deaths} += 4; $playerHoH{Harry}{kills} += 20;
    It does not matter if Harry already exists or not. If he doesn't Perl makes him for you. The += causes any existing values to be added to the deaths or kills. In the case where Harry is "brand new", this still works because the new entry starts out at essentially a 0 numeric value for the purposes of doing the addition here.

    Maybe some more code will help...I show how to print the HoH manually using 2 different but equivalent syntax's..

    #!/usr/bin/perl -w use strict; my %playerHoH = ( Bennie => { deaths => 1, kills => 13 }, Bob => { deaths => 12, kills => 15 }, Jane => { deaths => 0, kills => 30 }, mary => { deaths => 4, kills => 20 }, ); $playerHoH{Harry}{deaths} += 4; $playerHoH{Harry}{kills} += 20; foreach my $name (keys %playerHoH) { print "$name "; #prints: Jane Bob Harry mary Bennie } print "\n"; #again Jane Bob mary Bennie must be and are unique. #the hash forces them to be that way foreach my $name (keys %playerHoH) { my $hash_ref = $playerHoH{$name}; #the value is a reference #to another hash! foreach my $key (keys %$hash_ref) { ### these 2 formulations are equivalent and print ### the same thing print "One way: $name: $key => $hash_ref->{$key}\n"; print "Another way: $name: $key => $playerHoH{$name}{$key}\n"; } print "\n"; } =above prints: One way: Jane: deaths => 0 Another way: Jane: deaths => 0 One way: Jane: kills => 30 Another way: Jane: kills => 30 One way: Bob: deaths => 12 Another way: Bob: deaths => 12 One way: Bob: kills => 15 Another way: Bob: kills => 15 One way: Harry: deaths => 4 Another way: Harry: deaths => 4 One way: Harry: kills => 20 Another way: Harry: kills => 20 One way: mary: deaths => 4 Another way: mary: deaths => 4 One way: mary: kills => 20 Another way: mary: kills => 20 One way: Bennie: deaths => 1 Another way: Bennie: deaths => 1 One way: Bennie: kills => 13 Another way: Bennie: kills => 13 =cut
    I suggest looking at Some tutorials on hashes
      Oh now I get it, super smart lol :P thx!