package App::WRT::Sort; use strict; use warnings; use 5.10.0; use Carp; use base qw(Exporter); our @EXPORT_OK = qw(sort_entries); =pod =head1 NAME App::WRT::Sort - functions for sorting wrt entry lists =head1 SYNOPSIS use App::WRT::Sort qw(sort_entries); my (@sorted) = sort_entries(@unsorted); =head1 DESCRIPTION This makes an effort to sort a list of entries, which may include both simple dates and names, or a combination thereof, reasonably. The main goal is to have dates sorted in order, followed by alphanumeric names. =head1 FUNCTIONS =over =item sort_entries(@entries) Sort a list of entries by converting them to an array with an easily sortable string format as the second value, sorting these arrayrefs by that value, and then re-mapping them to the original values. See here: L =cut sub sort_entries { my (@entries) = @_; return map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [$_, sortable_from_entry($_)] } @entries; } =item sortable_from_entry($entry) Get a sortable string value that does (more or less) what we want. In this case, it pads numeric components of the path out to 5 leading 0s and leaves everything else alone. =cut sub sortable_from_entry { my ($entry) = @_; my @parts = map { my $padded; if (m/^\d+$/) { # There's a year 100k bug here, but I guess I'll cross that bridge when I # come to it: $padded = sprintf("%05d", $_); } else { $padded = $_; } $padded; } split '/', $entry; return join '', @parts; } =back =cut 1;