Read perlref. Again. Play with the structures.
Your %HOH corrected:
%HOH = ( # not [ ! 1 => { # key => 1, person => "Mike", possession => "wallet, keys, car, house", age => 25, }, 2 => { # key => 2, person => "Mike", possession => "dog, cat, baseball bat", age => 25, }, 3 => { # key => 3, person => "Dave", possession => "pony, house, car, keys", age => 21, }, ); # not ] !
Likewise for your @AOH. Spot the error. Read perldata and perlref, again. Now to your ostensible problem:
How would one consolidate the hash of hashes to another hash of hashes or array of hashes so that if person and age were same, the possession would be a merge of the possession ... resulting in one entry per person/age combination but with all possessions in the array(list) of values for the possession key?
use Data::Dumper; use strict; use warnings; my %HOH = ( # not [ ! 1 => { # key => 1, person => "Mike", possession => "wallet, keys, car, house", age => 25, }, 2 => { # key => 2, person => "Mike", possession => "dog, cat, baseball bat", age => 25, }, 3 => { # key => 3, person => "Dave", possession => "pony, house, car, keys", age => 21, }, ); # not ] ! my %NewHOH; # consolidated hash. { # limit scope of %seen to this block my %seen; # intermediate hash. Key is "person:age" for my $key (keys %HOH) { # iterate over the keys of the hash my $val = $HOH{$key}; # get the value - an anonymous hash my $composite_key = join ":", $HOH{$key}->{person}, $HOH{$key}->{a +ge}; if ($seen{$composite_key}++) { # note: post increment! # we make the comma-separated string into an array. # then we build a hash using the array elements as keys. # this avoids duplicates. We later convert that back. my @possessions = split /,\s*/, $HOH{$key}->{possession}; for my $item (@possessions) { $NewHOH{$composite_key}->{possession}->{$item}++; } } else { # first occurence of this "person:age" key $NewHOH{$composite_key} = $HOH{$key}; # same as above. Make a hash of the items of "possession" $NewHOH{$composite_key}->{possession} = { map { $_, 1 } split /,\s*/, $HOH{$key}->{possession} }; + # record the first key, we'll use that to re-key the hash $NewHOH{$composite_key}->{key} = $key; } } } # now get rid of composite keys and make the anon arrays # of the "possession" value into a string for my $key ( keys %NewHOH ) { my $val = delete $NewHOH{$key}; # returns the anon hash my $new_key = delete $val->{key}; # old key which was remembered $NewHOH{$new_key} = $val; $val->{possession} = join ", ", keys %{$val->{possession}}; } # debug output $Data::Dumper::Indent = 1; my $d = Data::Dumper->new( [\%NewHOH], ['NewHOH'], ); print $d->Dump; __END__ $NewHOH = { '1' => { 'possession' => 'house, keys, baseball bat, cat, dog, car, wallet' +, 'person' => 'Mike', 'age' => 25 }, '3' => { 'possession' => 'keys, house, pony, car', 'person' => 'Dave', 'age' => 21 } };
Note that after __END__, the output shows an anonymous hash! See Data::Dumper, map and split. See perlref, perldata.
In reply to Re: Confused on handling merging values for hash of hashes
by shmem
in thread Confused on handling merging values for hash of hashes
by hiyall
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |