in reply to Unusual sorting requirements; comparing three implementations.

You can exploit that fact that sort is stable, and do two passes over the data:

sub two_pass { my @sorted = sort { $b->title =~ /Manager/ <=> $a->title =~ /Manager/ } sort { $a->name cmp $b->name } @employees; }

Moo wouldn't install on my machine, so I used Mo instead for benchmarking:

Rate obvious subtle two_pass functional obvious 173/s -- -22% -30% -61% subtle 222/s 28% -- -11% -50% two_pass 249/s 44% 12% -- -44% functional 444/s 156% 100% 79% --

Of course it does more than necessary (splitting into managers and non-managers first is less work, because the lists to sort are shorter), but the speed still isn't too bad.

Update: and here's a Perl 6 solution:

use v6; class Person { has $.name; has $.title; } sub person($name, $title) { Person.new(:$name, :$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 @sorted = @employees.classify({ .title ~~ /Manager/ ?? 'manager' !! 'staff'} +)\ .sort.map(*.value.sort(*.name)); say .perl for @sorted;

Output:

Person.new(name => "Alice", title => "Sales Manager") Person.new(name => "Carol", title => "Marketing Manager") Person.new(name => "Greg", title => "Finance Manager") Person.new(name => "Bob", title => "Customer Services") Person.new(name => "Dave", title => "Janitor") Person.new(name => "Eve", title => "Tech Support") Person.new(name => "Fred", title => "Receptionist")

.classify returns a Hash, and .sort on a Hash returns a list of Pair object, sorted by key and then by value. Since 'manager' lt 'staff', this puts all the managers first. Then each of the lists is sorted by name.


Comment on Re: Unusual sorting requirements; comparing three implementations.
Select or Download Code