my $data; my $sorted; while( <> ) { my @cols = split /,/, $_; for my $i ( 0 .. $#cols ) { #counter for the unique element $data->[ $i ]->{ $cols[ $i ] }->[ 0 ]++; #undefine the array element in sorted if a $data reference was previously defined undef $sorted->[ $i ]->{ \$data->[ $i ]->{ $cols[ $i ] }->[ 1 ] } if $data->[ $i ]->{ $cols[ $i ] }->[ 1 ]; #elements in $sorted my $stack = $#{ $sorted->[ $i ] }; #store the new reference to the $data record at the top of $sorted's stack $sorted->[ $i ]->[ $stack ] = \$data->[ $i ]->{ $cols[ $i ] }; #reference to place in $sorted so that it may be undefined later if necessary $data->[ $i ]->{ $cols[ $i ] }->[ 1 ] = \$sorted->[ $i ]->[ $stack ]; } } #then, you could just loop through sorted. bypassing: # sort { $data->[ $i ]->{ $a } <=> $data->[ $i ]->{ $b } # } keys %{ $data->[ $i ] } # with something like for my $i ( 0 .. $#{ $sorted } } ) { foreach my $j ( 0 .. $#{ $sorted->[ $i ] } ) { print "column ". $i . ":" . $sorted->[ $i ]->[ $j ]->[ 1 ] . " had " . $sorted->[ $i ]->[ $j ]->[ 0 ] . " duplicates\n" if( $sorted->[ $i ]->[ $j ] ); } }