use strict;
use warnings;
use Data::Dumper;
my @in = qw(
john,doe,sam,jr
albert,simpson
barry,white,,III
harry,potter
steve,zurk,james,sr
);
my @in_split = map { [ split /,/ ] } @in;
my @in_hashed = map {
{
fname => $_->[0],
lname => $_->[1],
mname => $_->[2],
surname => $_->[3],
}
} @in_split;
my @in_sorted = sort {
(
defined $a->{mname}
&& defined $b->{mname}
&& (
lc substr( $a->{mname}, 0, 1 ) cmp lc substr( $b->{mname},
+ 0, 1 )
)
)
|| (
lc substr( $a->{fname}, 1, 1 ) cmp lc substr( $b->{fname}, 1,
+1 ) )
|| (
lc substr( $a->{lname}, -1, 1 ) cmp lc substr( $b->{lname}, -1
+, 1 ) )
} @in_hashed;
print Dumper \@in_sorted;
__END__
$VAR1 = [
{
'lname' => 'white',
'mname' => '',
'fname' => 'barry',
'surname' => 'III'
},
{
'lname' => 'potter',
'mname' => undef,
'fname' => 'harry',
'surname' => undef
},
{
'lname' => 'simpson',
'mname' => undef,
'fname' => 'albert',
'surname' => undef
},
{
'lname' => 'zurk',
'mname' => 'james',
'fname' => 'steve',
'surname' => 'sr'
},
{
'lname' => 'doe',
'mname' => 'sam',
'fname' => 'john',
'surname' => 'jr'
}
];
Formatting is by perltidy.
Since some records don't have a middle name, you have to check if that's defined to avoid warnings. In that case, I've skipped comparing on middle name. If you want undef names to sort in a particular place (first or last, I'd guess), then you could code for that.