Perl 哈希嵌套

# 1.记住Perl中的Hash表要用(),而不是中括号,或者花括号
# 2.但是如果属于嵌套内容,那么就不能再用小括号了,必须是花括号{}.
# 3.如果需要继续嵌套数组,记得使用中括号来表示数组[]

9.4. Hashes of Hashes

A multidimensional hash is the most flexible of Perl's nestedstructures. It's like building up a record that itself contains otherrecords. At each level, you index into the hash with a string (quotedwhen necessary). Remember, however, that the key/value pairs in thehash won't come out in any particular order; you can use the sortfunction to retrieve the pairs in whatever order you like.

9.4.1. Composition of a Hash of Hashes

You can create a hash of anonymous hashes as follows:

%HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",  # Key quotes needed.
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);
To add another anonymous hash to %HoH, you can simply say:
$HoH{ mash } = {
    captain  => "pierce",
    major    => "burns",
    corporal => "radar",
};

9.4.2. Generation of a Hash of Hashes

Here are some techniques for populating a hash of hashes. To read froma file with the following format:

flintstones: husband=fred pal=barney wife=wilma pet=dino
you could use either of the following two loops:
while ( <> ) {
    next unless s/^(.*?):\s*//;
    $who = $1;
    for $field ( split ) {
        ($key, $value) = split /=/, $field;
        $HoH{$who}{$key} = $value;
    }
}

while ( <> ) {
    next unless s/^(.*?):\s*//;
    $who = $1;
    $rec = {};
    $HoH{$who} = $rec;
    for $field ( split ) {
        ($key, $value) = split /=/, $field;
        $rec->{$key} = $value;
    }
}
If you have a subroutine get_family that returns a list ofkey/value pairs, you can use it to stuff %HoH with either ofthese three snippets:
for $group ( "simpsons", "jetsons", "flintstones" ) {
    $HoH{$group} = { get_family($group) };
}

for $group ( "simpsons", "jetsons", "flintstones" ) {
    @members = get_family($group);
    $HoH{$group} = { @members };
}

sub hash_families {
    my @ret;
    for $group ( @_ ) {
        push @ret, $group, { get_family($group) };
    }
    return @ret;
}
%HoH = hash_families( "simpsons", "jetsons", "flintstones" );
You can append new members to an existing hash like so:
%new_folks = (
    wife => "wilma",
    pet  => "dino";
);
for $what (keys %new_folks) {
    $HoH{flintstones}{$what} = $new_folks{$what};
}

9.4.3. Access and Printing of a Hash of Hashes

You can set a key/value pair of a particular hash as follows:

$HoH{flintstones}{wife} = "wilma";
To capitalize a particular key/value pair, apply a substitution toan element:
$HoH{jetsons}{'his boy'} =~ s/(\w)/\u$1/;
You can print all the families by looping through the keys of theouter hash and then looping through the keys of the inner hash:
for $family ( keys %HoH ) {
    print "$family: ";
    for $role ( keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
In very large hashes, it may be slightly faster to retrieve bothkeys and values at the same time using each (which precludes sorting):
while ( ($family, $roles) = each %HoH ) {
    print "$family: ";
    while ( ($role, $person) = each %$roles ) {
        print "$role=$person ";
    }
    print "\n";
}
(Unfortunately, it's the large hashes that really need to be sorted, oryou'll never find what you're looking for in the printout.) You cansort the families and then the roles as follows:
for $family ( sort keys %HoH ) {
    print "$family: ";
    for $role ( sort keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
To sort the families by the number of members (instead ofASCIIbetically (or utf8ically)), you can use keys in a scalar context:
for $family ( sort { keys %{$HoH{$a}} <=> keys %{$HoH{$b}} } keys %HoH ) {
    print "$family: ";
    for $role ( sort keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
To sort the members of a family in some fixed order, you can assignranks to each:
$i = 0;
for ( qw(husband wife son daughter pal pet) ) { $rank{$_} = ++$i }

for $family ( sort { keys %{$HoH{$a}} <=> keys %{$HoH{$b}} } keys %HoH ) {
    print "$family: ";
    for $role ( sort { $rank{$a} <=> $rank{$b} } keys %{ $HoH{$family} } ) {
        print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}

参考:http://docstore.mik.ua/orelly/perl/prog3/ch09_04.htm






你可能感兴趣的:(Perl)