use Sort::Key qw(keysort nkeysort ikeysort); @by_name = keysort { "$_->{surname} $_->{name}" } @people; # sorting by a numeric key: @by_age = nkeysort { $_->{age} } @people; # sorting by a numeric integer key: @by_sons = ikeysort { $_->{sons} } @people;
It is faster (usually much faster) and uses less memory than other alternatives implemented around perl sort function (ST, GRT, etc.).
Multi-key sorting functionality is also provided via the companion modules Sort::Key::Multi, Sort::Key::Maker and Sort::Key::Register.
@sorted = keysort { CALC_KEY($_) } @data
that is conceptually equivalent to
@sorted = sort { CALC_KEY($a) cmp CALC_KEY($b) } @data
and where "CALC_KEY($_)" can be any expression to extract the key value from $_ (not only a subroutine call).
For instance, some variations are "nkeysort" that performs a numeric comparison, "rkeysort" that orders the data in descending order, "ikeysort" and "ukeysort" that are optimized versions of "nkeysort" that can be used when the keys are integers or unsigned integers respectively, etc.
Also, inplace versions of the sorters are provided. For instance
keysort_inplace { CALC_KEY($_) } @data
that is equivalent to
@data = keysort { CALC_KEY($_) } @data
but being (a bit) faster and using less memory.
The full list of subroutines that can be imported from this module follows:
Inside "{ CALC_KEY }", the object is available as $_.
For example:
@a=({name=>john, surname=>smith}, {name=>paul, surname=>belvedere}); @by_name=keysort {$_->{name}} @a;
This function honours the "use locale" pragma.
This function honours the "use integer" pragma, i.e.:
use integer; my @s=(2.4, 2.0, 1.6, 1.2, 0.8); my @ns = nkeysort { $_ } @s; print "@ns\n"
prints
0.8 1.6 1.2 2.4 2
For instance, it can be used to efficiently sort IP4 addresses:
my @data = qw(1.2.3.4 4.3.2.1 11.1.111.1 222.12.1.34 0.0.0.0 255.255.255.0) 127.0.0.1); my @sorted = ukeysort { my @a = split /\./; (((($a[0] << 8) + $a[1] << 8) + $a[2] << 8) + $a[3]) } @data;
For instance those constructions are equivalent:
@sorted = nsort @foo; @sorted = nkeysort { $_ } @foo; @sorted = sort { $a <=> $b } @foo;
They get a list of keys descriptions and return a reference to a multi-key sorting subroutine.
Types accepted by default are:
string, str, locale, loc, integer, int, unsigned_integer, uint, number, num
and support for additional types can be added via the register_type subroutine available from Sort::Key::Types or the more friendly interface available from Sort::Key::Register.
Types can be preceded by a minus sign to indicate descending order.
If the first argument is a reference to a subroutine it is used as the multi-key extraction function. If not, the generated sorters expect one as their first argument.
Example:
my $sorter1 = multikeysorter(sub {length $_, $_}, qw(int str)); my @sorted1 = &$sorter1(qw(foo fo o of oof)); my $sorter2 = multikeysorter(qw(int str)); my @sorted2 = &$sorter2(sub {length $_, $_}, qw(foo fo o of oof));
Companion modules Sort::Key::Multi, Sort::Key::Register, Sort::Key::Maker and Sort::Key::Natural.
Sort::Key::IPv4, Sort::Key::DateTime and Sort::Key::OID modules add support for additional datatypes to Sort::Key.
Sort::Key::External allows to sort huge lists that do not fit in the available memory.
Other interesting Perl sorting modules are Sort::Maker, Sort::Naturally and Sort::External.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available.