my @sorted = sort { if ($a->title =~ /Manager/ and not $b->title =~ /Manager/) { -1; } elsif ($b->title =~ /Manager/ and not $a->title =~ /Manager/) { 1; } else { $a->name cmp $b->name; } } @employees; #### my @sorted = sort { ($a->title !~ /Manager/) - ($b->title !~ /Manager/) or $a->name cmp $b->name; } @employees; #### use List::MoreUtils qw( part ); my @sorted = map { sort { $a->name cmp $b->name } @$_ } part { $_->title !~ /Manager/ } @employees; #### use v5.14; use strict; use warnings; use Test::More; package Person { use Moo; has name => (is => 'ro'); has title => (is => 'ro'); } sub Person { my ($name, $title) = @_; Person::->new(name => $name, title => $title); } my @employees = ( Person("Eve", "Tech Support"), Person("Alice", "Sales Manager"), Person("Dave", "Janitor"), Person("Fred", "Receptionist"), Person("Bob", "Customer Services"), Person("Greg", "Finance Manager"), Person("Carol", "Marketing Manager"), ); my @correct = ( Person("Alice", "Sales Manager"), Person("Carol", "Marketing Manager"), Person("Greg", "Finance Manager"), Person("Bob", "Customer Services"), Person("Dave", "Janitor"), Person("Eve", "Tech Support"), Person("Fred", "Receptionist"), ); OBVIOUS_APPROACH: { my @sorted = sort { if ($a->title =~ /Manager/ and not $b->title =~ /Manager/) { -1; } elsif ($b->title =~ /Manager/ and not $a->title =~ /Manager/) { 1; } else { $a->name cmp $b->name; } } @employees; is_deeply(\@sorted, \@correct, 'Obvious approach'); } SUBTLER_APPROACH: { my @sorted = sort { ($a->title !~ /Manager/) - ($b->title !~ /Manager/) or $a->name cmp $b->name; } @employees; is_deeply(\@sorted, \@correct, 'Subtler approach'); } FUNCTIONAL_APPROACH: { use List::MoreUtils qw( part ); my @sorted = map { sort { $a->name cmp $b->name } @$_ } part { $_->title !~ /Manager/ } @employees; is_deeply(\@sorted, \@correct, 'Functional approach'); } done_testing(); #### use v5.14; use strict; use warnings; use List::MoreUtils qw( part ); use Benchmark ':all'; package Person { use Moo; has name => (is => 'ro'); has title => (is => 'ro'); } my @employees = map { Person::->new( name => int(rand(999999)), title => int(rand(2))?'Staff':'Manager', ) } 0..200; sub obvious { my @sorted = sort { if ($a->title =~ /Manager/ and not $b->title =~ /Manager/) { -1; } elsif ($b->title =~ /Manager/ and not $a->title =~ /Manager/) { 1; } else { $a->name cmp $b->name; } } @employees; } sub subtle { my @sorted = sort { ($a->title !~ /Manager/) - ($b->title !~ /Manager/) or $a->name cmp $b->name; } @employees; } sub functional { my @sorted = map { sort { $a->name cmp $b->name } @$_ } part { $_->title !~ /Manager/ } @employees; } cmpthese(1000, { obvious => \&obvious, subtle => \&subtle, functional => \&functional, }); #### my @sorted = map { keysort { $_->name } @$_ } part { $_->title !~ /Manager/ } @employees;