If this is exactly what you need, davidrw's answer will not suffice, of course. In this case, instead of trying to do all the work in one multi-nested loop (whatever the nesting depth), I'd stick to do one thing at a time and proceed by steps. In this case, you should track the variations together with the other stuff:
#!/usr/bin/perl use strict; use warnings; use Storable qw( freeze thaw ); use Data::Dumper; my %bighash = ( 'Arizona'=> { 'ZOO_1' => [ '5','HIPPO1', ['feat1'],['feat2']], 'ZOO_2' => [ '10','HIPPO2',['feat1'],['feat2']], 'ZOO_3' => [ '2', 'PUMA1', ['feat1'],['feat2']], 'ZOO_5' => [ '13', 'PUMA2',['feat1'],['feat2']], }, 'Indiana' => { 'ZOO_2' => [ '10','HIPPO3', ['feat1'],['feat2']], 'ZOO_9' => [ '25','ZEBRA1', ['feat1'],['feat2']], 'ZOO_5' => [ '13','MONKEY1', ['feat1'],['feat2']], 'ZOO_6' => [ '23','ZEBRA2', ['feat1'],['feat2']], 'ZOO_3' => [ '2', 'PUMA3', ['feat1'],['feat2']], 'ZOO_5' => [ '1', 'PUMA4', ['feat1'],['feat2']], }, 'Nevada' => { 'ZOO_3' => [ '3', 'HIPPO4', ['feat1'],['feat2']], 'ZOO_7' => [ '11', 'HIPPO5', ['feat1'],['feat2']], 'ZOO_4' => [ '21', 'LION1', ['feat1'],['feat2']], 'ZOO_12' => [ '13','MONKEY2',['feat1'],['feat2']], }, ); my %animals; { # Scope reduction, could be put inside a function :) my %tmp; while ( my ($state, $zoos) = each %bighash ) { while ( my ($zoo, $row) = each %$zoos ){ my $animal = $row->[1]; (my $root = $animal) =~ s/\d+$//; $tmp{$root}{variations}{$animal} = 1; push @{$tmp{$root}{data}{$state}}, $zoo; } } # Now we traverse %tmp to create the needed structure foreach my $href (values %tmp) { # Use freeze/thaw from Storable to do deep hash copying my $frozen = freeze($href->{data}); $animals{$_} = thaw($frozen) foreach keys %{$href->{variations}} } } $Data::Dumper::Sortkeys = 1; print Dumper \%animals ;
$VAR1 = { 'HIPPO1' => { 'Arizona' => [ 'ZOO_1', 'ZOO_2' ], 'Indiana' => [ 'ZOO_2' ], 'Nevada' => [ 'ZOO_7', 'ZOO_3' ] }, 'HIPPO2' => { 'Arizona' => [ 'ZOO_1', 'ZOO_2' ], 'Indiana' => [ 'ZOO_2' ], 'Nevada' => [ 'ZOO_7', 'ZOO_3' ] }, 'HIPPO3' => { 'Arizona' => [ 'ZOO_1', 'ZOO_2' ], 'Indiana' => [ 'ZOO_2' ], 'Nevada' => [ 'ZOO_7', 'ZOO_3' ] }, 'HIPPO4' => { 'Arizona' => [ 'ZOO_1', 'ZOO_2' ], 'Indiana' => [ 'ZOO_2' ], 'Nevada' => [ 'ZOO_7', 'ZOO_3' ] }, 'HIPPO5' => { 'Arizona' => [ 'ZOO_1', 'ZOO_2' ], 'Indiana' => [ 'ZOO_2' ], 'Nevada' => [ 'ZOO_7', 'ZOO_3' ] }, 'LION1' => { 'Nevada' => [ 'ZOO_4' ] }, 'MONKEY2' => { 'Nevada' => [ 'ZOO_12' ] }, 'PUMA1' => { 'Arizona' => [ 'ZOO_5', 'ZOO_3' ], 'Indiana' => [ 'ZOO_5', 'ZOO_3' ] }, 'PUMA2' => { 'Arizona' => [ 'ZOO_5', 'ZOO_3' ], 'Indiana' => [ 'ZOO_5', 'ZOO_3' ] }, 'PUMA3' => { 'Arizona' => [ 'ZOO_5', 'ZOO_3' ], 'Indiana' => [ 'ZOO_5', 'ZOO_3' ] }, 'PUMA4' => { 'Arizona' => [ 'ZOO_5', 'ZOO_3' ], 'Indiana' => [ 'ZOO_5', 'ZOO_3' ] }, 'ZEBRA1' => { 'Indiana' => [ 'ZOO_9', 'ZOO_6' ] }, 'ZEBRA2' => { 'Indiana' => [ 'ZOO_9', 'ZOO_6' ] } };
For some considerations about this deep (or shallow) copy stuff you can also start from this thread, and in particular from pelagic's answer.foreach my $href (values %tmp) { $animals{$_} = $href->{data} foreach keys %{$href->{variations}} }
Flavio
perl -ple'$_=reverse' <<<ti.xittelop@oivalf
In reply to Re: Counting Variations of Key in a Hash
by polettix
in thread Counting Variations of Key in a Hash
by neversaint
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |