Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Please help to sort array

I have an array contains the list for the following:

@arr=(' F1.jpg F10.jpg F11.jpg F12.jpg F1a.jpg F1b.jpg F2.jpg F3.jpg F4.jpg F5.jpg F6.jpg ');

And I need sorted array for the follwoing

@arr=(' F1a.jpg F1b.jpg F1.jpg F2.jpg F3.jpg F4.jpg F5.jpg F6.jpg F10.jpg F11.jpg F12.jpg ');

Is there any coding or any modules.

Replies are listed 'Best First'.
Re: Sort Array
by davido (Cardinal) on May 21, 2005 at 04:41 UTC

    Ok, I'm acting under the assumption that the leading "F" in your filenames is always going to be "F". If not, this might not do everything you need. Here goes:

    use strict; use warnings; my @arr=( qw/ F1.jpg F10.jpg F11.jpg F12.jpg F1a.jpg F1b.jpg F2.jpg F3.jpg F4.jpg F5.jpg F6.jpg /); print "$_\n" for sort { my( $aye ) = $a =~ m/(\d+)/; my( $bee ) = $b =~ m/(\d+)/; $aye <=> $bee || $a cmp $b } @arr;

    Here's how it works: Isolate the digits in each comparison, and do a numeric comparison just on the digits. If the numeric comparison equates to equality, the logical OR short circuit operator falls through to the string comparison. So you get numeric first, and asciibetical order second. I hope that's close to what you were looking for.

    If the dataset is large and you intend on running the sort more than once, you might benefit from a Schwartzian Transform, but my guess is that you really don't need to be that concerned with efficiency.

    For more info on sorting, read sort.

    Update:I just noticed you want F1.jpg to appear after F1a.jpg. That's an unusual sort order. Are you sure you want that? Anyway, I've given at least enough of a building-block example upon which you can construct even more complex sort routines to satisfy whatever definition of "sorted" you wish to come up with. :) Enjoy!.


    Dave

Re: Sort Array
by TedPride (Priest) on May 21, 2005 at 07:14 UTC
    use strict; while (<DATA>) { chomp; push @_, $_; } print join "\n", sort { my ($d1, $w1) = $a =~ m/F(\d+)(\w+)?/; my ($d2, $w2) = $b =~ m/F(\d+)(\w+)?/; $d1 <=> $d2 || mcmp($w1, $w2) } @_; sub mcmp { return 0 if $_[0] eq $_[1]; return -1 if !$_[1]; return 1 if !$_[0]; return $_[0] cmp $_[1]; } __DATA__ F1.jpg F10.jpg F11.jpg F12.jpg F1a.jpg F1b.jpg F2.jpg F3.jpg F4.jpg F5.jpg F6.jpg
Re: Sort Array
by ihb (Deacon) on May 21, 2005 at 13:32 UTC

    use Sort::Naturally; @arr = nsort @arr;
    Done!

    ihb

    See perltoc if you don't know which perldoc to read!

      I didn't know that existed. Interesting.

      I was just about to suggest using Sort::Versions.



      ($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
      =~y~b-v~a-z~s; print
Re: Sort Array
by polettix (Vicar) on May 21, 2005 at 15:20 UTC
    This is not a solution for your post, only a warning about your array - you won't be able to sort it as it is!

    Please read carefully how davido builds @arr - he's using the qw (quote word) operator, differently from you that are using single quotes. In this way, you're actually putting only 1 element inside the array, that is one big string containing all the filenames separated by newlines. davido's approach, on the other side, lets you have an element in @arr for each filename that is compound of a single word (and this is fine in your case, because your filenames don't have spaces). Caveat emptor.

    Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

    Don't fool yourself.
Re: Sort Array
by salva (Canon) on May 21, 2005 at 08:09 UTC
    A couple of days ago I released a new version of Sort::Key supporting multikey sorting:
    use Sort::Key::Maker sort_pic_names => # define how to extract the keys sub { /^F(\d*)(\w*)/; $1, ($2||"\xff") }, # and their types qw(number string); my @arr = ... ; # and just use the new sorter my @sorted_arr = sort_pic_names @arr;
    update: I have notice that there is some bug in the module that causes the multikey functionality to corrupt memory in some systems... so don't use it yet!
Re: Sort Array
by BUU (Prior) on May 21, 2005 at 04:38 UTC
    perldoc -f sort