Simply replace the month name with a string that sorts as you like (using the default sort), then undo that replacement after the sort:

my @files= <*>; @files= do { my @mo= ( qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec), 'a'..'l' ); my %mo; @mo{@mo}= reverse @mo; grep { s/^(.)/$mo{$1}/ } sort grep { s/^(...)/$mo{$1}/ } @files; };
So we set up %mo so that $mo{Jan} is 'a' and $mo{a} is 'Jan'. Then we read the "grep sort grep" from the bottom up: Take the unsorted list of file names, take the first 3 letters of each file name and replace it with appropriate letter, sort the list of modified file names, replace the first letter of the modified file names with the month abbreviations, return the sorted list.

Note that this assumes that we have a leading zero in front of single-digit days of the month and that all of the month names are capitalized exactly as we expect. If not, then we need to account for that as well. (It also doesn't deal with invalid file names.)

my @files= <*>; @files= do { my @mo= qw(jan feb mar apr may jun jul aug sep oct nov dec); my %mo; @mo{@mo}= 0..$#mo; grep { s/^[^-]*-// } sort grep { # Replace "JAN1" with "a01-JAN1": s/^(...)(\d\d?)/sprintf "%s%02d-%s",$mo{lc$1},$2,$1.$2/e or $_= "?-$_"; 1; } @files; };
Update: You see, this is why Perl needs a 'filter' primitive. Neither map nor grep is quite the right tool for this job and map seems almost seductively right for it which results in people making mistakes like I just did.

In the first snippet, I originally had 'map' instead of 'grep'. 'map' will give back the return value from the s/// operator, which is not the modified string.

The second snippet had the same mistake but when I fixed it I also decided to deal with filenames that aren't named as we expected.

It is easy to characterize this as an abuse of grep. I tend to agree. (:

        - tye (just that sort of guy... sort of)

In reply to (tye)Re: sorting an array with an array by tye
in thread sorting an array with an array by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.