my $orderby = "age"; # or name, dob, etc my $direction = "ASC"; # or DESC my $sortfunc = getsort($direction); foreach my $id (sort $sortfunc keys %hash) { print "$id - $hash{$id}{$orderby}\n"; } # end-foreach sub getsort { my ($direction) = @_; my $sense = $direction eq "DESC" ? -1 : 1; return sub { ( $hash{$a}{$orderby} <=> $hash{$b}{$orderby} || $hash{$a}{$orderby} cmp $hash{$b}{$orderby}) * $sense; } }