Powerful Sorting
#!/usr/bin/perl -w

use strict;

my %employee = (
		"0080" => { lname => 'Smith',
			        fname => 'Robert',
			        age   => 42, },
		"0901" => { lname => 'Ivan',
			        fname => 'Mazepa',
			        age   => 102, },
		"0332" => { lname => 'Smith',
			        fname => 'Linda',
			        age   => 39, },
		"0014" => { lname => 'Bird',
			        fname => 'Johne',
			        age   => 48, },
		);

# PROBLEM: sort output by last name.
for ( sort { $employee{$a}{'lname'} cmp $employee{$b}{'lname'} } 
      keys %employee )
{
	printf "%04d. %-10s %s\n", $_,
		$employee{$_}->{'lname'},
		$employee{$_}->{'fname'};
}
# 0014. Bird       Johne
# 0901. Ivan       Mazepa
# 0080. Smith      Robert
# 0332. Smith      Linda

# PROBLEM: sort output by last,first name.
#---------------------------------------------------
for ( sort { sorted1($_) } keys %employee )
{
	printf "%04d. %-10s %s\n", $_,
		$employee{$_}->{'lname'},
		$employee{$_}->{'fname'};
}
sub sorted1
{
	$employee{$a}{'lname'} cmp $employee{$b}{'lname'}
	||
	$employee{$a}{'fname'} cmp $employee{$b}{'fname'}
}
# 0014. Bird       Johne
# 0901. Ivan       Mazepa
# 0332. Smith      Linda
# 0080. Smith      Robert

# PROBLEM: we have large hash of data. From some table or
# .cdb file we've got number of IDs. We need to print only
# records with these IDs.
#---------------------------------------------------
my @id = qw(0080 0901 0332);
for (
	map [ $employee{$_}{'lname'},$employee{$_}{'fname'} ],
	@id )
{
	print "$_->[0]  $_->[1]\n";
}
# or even simpler
# for ( @id ) {
#	print "$employee{$_}{'lname'} $employee{$_}{'fname'}\n";
# }
# Smith  Robert
# Ivan  Mazepa
# Smith  Linda

# Now sort this output by last, first names.
#---------------------------------------------------
for  (
	sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] }
	map [ $employee{$_}{'lname'},$employee{$_}{'fname'} ],
	@id )
{
	print "$_->[0]  $_->[1]\n";
}
# Ivan  Mazepa
# Smith  Linda
# Smith  Robert

# For readability, put code of the sorting and the mapping
# in subroutines.
#--------------------------------------------------
for ( sort { sort_by_last_first($_) }
	  map { mapped($_) } @id )
{
	print "$_->[0]  $_->[1]\n";
}

sub sort_by_last_first {
	$a->[0] cmp $b->[0] || $a->[1] cmp $b->[1];
}
sub mapped {
	[ $employee{$_}{'lname'},$employee{$_}{'fname'} ];
}
# Ivan  Mazepa
# Smith  Linda
# Smith  Robert