use strict; my @subfields = qw( REQ POS LENGTH data FILTER ); my @mydata = ( [ this_type => [ 'N', 34, 10, ' ' x 10, \&default_filter ] ], [ that_type => [ 'Y', 34, 10, ' ' x 10, \&default_filter ], [ 'Y', 35, 10, ' ' x 10, \&default_filter ] ], ); my %hash; for my $d ( @mydata ) { my $type = shift @$d; for my $data ( @$d ) { my $field; @{ $field }{ @subfields } = @$data; push @{ $hash{ $type } }, $field; } } __END__ DB<2> x \%hash 0 HASH(0x82ea2dc) 'that_type' => ARRAY(0x8449fa0) 0 HASH(0x8449f10) 'FILTER' => CODE(0x814cdd4) -> &CODE(0x814cdd4) in ??? 'LENGTH' => 10 'POS' => 34 'REQ' => 'Y' 'data' => ' ' 1 HASH(0x8449fac) 'FILTER' => CODE(0x814cdd4) -> REUSED_ADDRESS 'LENGTH' => 10 'POS' => 35 'REQ' => 'Y' 'data' => ' ' 'this_type' => ARRAY(0x8449ef8) 0 HASH(0x8449e20) 'FILTER' => CODE(0x814cdd4) -> REUSED_ADDRESS 'LENGTH' => 10 'POS' => 34 'REQ' => 'N' 'data' => ' '