#!/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' ] } }; #### foreach my $href (values %tmp) { $animals{$_} = $href->{data} foreach keys %{$href->{variations}} }