my %all = ( p => {}, v => {} ); my %s; foreach my $row ( @results ){ $all{p}->{ $row->{p_id} } = 1; $all{v}->{ $row->{v_id} } = 1; $s{ $row->{v_id} }->{ $row->{p_id} } = $row->{s_id}; } my @p = sort keys %{$all{p}}; my @v = sort keys %{$all{v}}; print join("|", " ", map { sprintf(" p_%-2d ",$_) } @p ), "\n"; print "-"x(7*(@p+1)) . "\n"; foreach my $v ( @v ){ # note hash slice print join( "|", # delim sprintf(" v_%-2d ",$v), # first column map { defined($_) ? sprintf(" s_%-2d ",$_) : " " # format accordingly } @{$s{$v}}{ @p } # all the s values for the 'p' columns; done via a hash slice ), "\n"; }