SPUG: Slice of HashOfHash
Paul Goracke
paul at goracke.org
Wed Nov 15 16:51:44 PST 2006
Eric.D.Peterson at alltel.com wrote:
> How can I make a new hash or loop through this HoH where husband =
> "fred"?
>
> I've been reading up on slices and printing hashes, but I can't seem to
> find an example or description on playing with HoH subsets. I've tried
> looping through the full HoH and adding those desired elements to a new
> HoH but that seems awkward and not quite right & cumbersome. So I
> thought I'd ask ya'll for some help.
Many ways of doing it, all of which use a loop/map/grep that I can think
of. Two I can think of w/ your current data structure (I'm a bit
paranoid about checking for a defined key before string comparing):
# grep filter for entries with 'husband'='fred',
# then add that key and its hashref
my %sub = map { $_ => $HoH{$_} }
grep { $HoH{$_}{'husband'} && $HoH{$_}{'husband'} eq 'fred' }
keys %HoH;
# or loop through w/ 'each', which makes it easier to follow the key/obj
my %sub2 = ();
while ( my ($key,$obj) = each %HoH ) {
$sub2{$key} = $obj
if ( $obj->{'husband'} && $obj->{'husband'} eq 'fred' );
}
In a case like this, I tend to "smuggle" the key into the object hashref
itself so I can operate on just the hashref, instead of trying to keep
track of the key and ref--if you change your data by:
while ( my ($key,$obj) = each %HoH ) {
$obj->{'_key'} = $key;
}
you can then do:
my %sub3 = map { ($_->{'husband'} && $_->{'husband'} eq 'fred')
? ( $_->{'_key'} => $_ ) : () }
values %HoH;
# or
my %sub4 = ();
$sub4{$_->{'_key'}} = $_
for grep { $_->{'husband'} && $_->{'husband'} eq 'fred' }
values %HoH;
--
pg
More information about the spug-list
mailing list