use strict; use warnings; my %hoa1 = ( 'key1' => ["A","B","C","D"], 'key2' => ["A","C","D","B"], 'key3' => ["C","A","D","H"], 'key4' => ["A","B","I","C"], ); my %hoa2 = ( 'key1' => ["A","D"], 'key2' => ["A","B"], 'key3' => ["C","H"], ); print_aoa( 'AoA1', align_array( %hoa1 ) ); print_aoa( 'AoA2', align_array( %hoa2 ) ); sub align_array { my %h = @_; my @keys = sort keys %h; # huh? why should sort order # dictate the reference array? my $ref = $h{ $keys[ 0 ] }; my @ret = map [ $_ ], @$ref; for my $i ( 0 .. $#{ $ref } ) { # $i determines the row in @ret my $elem = $ref->[ $i ]; for my $j ( 1 .. $#keys ) { # $j determines the col in @ret my $arr = $h{ $keys[ $j ] }; $ret[ $i ][ $j ] = '-'; for my $k ( 0 .. $#{ $arr } ) { if ( $elem eq $arr->[ $k ] ) { $ret[ $i ][ $j ] = $elem; splice @$arr, 0, $k + 1; last; } } } } return \@ret; } sub print_aoa { my ( $name, $aoa ) = @_; print '@', $name, ' = (', $/; for my $arr ( @$aoa ) { print ' [', join( ',', @$arr ), ']', $/; } print ')', $/; } __END__ @AoA1 = ( [A,A,A,A] [B,B,-,B] [C,-,-,C] [D,-,D,-] ) @AoA2 = ( [A,A,-] [D,-,-] )