|
|
- 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<https://en.wikipedia.org/wiki/Schwartzian_transform>
-
- =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;
|