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();