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

Hello everyone !!

I have to sort a hash by it's values, that's quite simple if I want a numeric sort or regular sort (with cmp)separately.
How can I sort the list:
@list = qw(nfs-4 afp-2 cifs-8 nfs-2 cifs-1 afp-7 cifs-11);
In order to get:
@sortedList = qw(afp-2 afp-7 cifs-1 cifs-8 cifs-11 nfs-2 nfs-4);
There are both string sorting and numeric sorting (in order not to get cifs-1 cifs-11 cifs-8).

anyone to the rescue?

Thanks.

Hotshot

Replies are listed 'Best First'.
Re: sorting question
by Abigail-II (Bishop) on Aug 01, 2002 at 15:05 UTC
    my @sortedList = map {my ($f, $s) = split /-/; "$f-" . ($s + 0)} sort map {sprintf "%s-%02d" => split /-/} @list;
    Abigail
Re: sorting question
by redsquirrel (Hermit) on Aug 01, 2002 at 15:10 UTC
    my @list = qw(nfs-4 afp-2 cifs-8 nfs-2 cifs-1 afp-7 cifs-11); print sort fooSort @list; sub fooSort { my @a = split '-', $a; my @b = split '-', $b; $a[0] cmp $b[0] || $a[1] <=> $b[1] }
    --Dave

    update: I like Abigail-II's Schwartzian Guttman-Rosler Transform! ++!

      What Schwartzian Transform? I made use of a technique known as the "Guttman-Rosler Transform".

      Abigail

Re: sorting question
by Tomte (Priest) on Aug 01, 2002 at 15:16 UTC
    @list = qw(nfs-4 afp-2 cifs-8 nfs-2 cifs-1 afp-7 cifs-11); sub my_sort { my ($as,$an) = split( /-/,$a,2); my ($bs,$bn) = split( /-/,$b,2); return ($_ = ($as cmp $bs)) ? $_ : ($an <=> $bn); } @sorted = sort my_sort @list print $_ . ", " for @sorted; __END__ afp-2, afp-7, cifs-1, cifs-8, cifs-11, nfs-2, nfs-4,

    works for your example list, may not be very perlish though

    regards,
    tomte
Re: sorting question
by Jaap (Curate) on Aug 01, 2002 at 19:57 UTC
    More generally, what you want is called Natural Sort. There's a module in CPAN that can sort naturally for you.

    Is that Guttman-Rosler thing also about natural sorting?